Hello, I haven't tried this code (nice, thanks), yet, but have a few comments.
- message(String) method just prints to System.out, yet there are separate /explicit System.out calls. Shouldn't they all use message(String)? - Should those 2 Jars in lib be in CVS? Is so, it looks like they got missed. They are mentioned in lib/README. Maybe we are supposed to put them there ourselves, if we want. - It seems that this is an interactive command line client with a required prompt from which you enter commands (didn't try this sw yet, so maybe the prompt is not required). This is nice, but I was wondering if the code be modified to also act like most other UNIX shell command, without the prompt. That way I could pipe its output to any number of the other useful UNIX commands that read stdin (e.g. sort, wc, grep, etc.) Thanks and thanks, Otis --- [EMAIL PROTECTED] wrote: > ehatcher 2003/12/10 18:07:45 > > Added: contributions/lucli README build.xml run.sh > contributions/lucli/META-INF MANIFEST.MF > contributions/lucli/lib README > contributions/lucli/src/lucli Completer.java > LuceneMethods.java Lucli.java > Log: > contribution from Dror Matalon > > Revision Changes Path > 1.1 > jakarta-lucene-sandbox/contributions/lucli/README > > Index: README > =================================================================== > lucli (pronounced Luckily) is the Lucene Command Line Interface. > > INSTALLATION > > Edit the run.sh shell script > 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 > > If you add the -r command line parameter lucli will try to use a > shared library > to enable things like tab completion and history. Unfortunately > Java doesn't support > this capability natively so you'll need a shared library for this. > I'm including one > that worked for me with Debian Linux. > For more details about GNU readline and java see > http://java-readline.sourceforge.net/ > which is the library that lucli uses. > > > Documentation > > There is none :-). Type help at the command line or read the code. > > Enjoy > > Dror Matalon > [EMAIL PROTECTED] > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/build.xml > > Index: build.xml > =================================================================== > <project name="lucli" default="build" basedir="."> > > <!-- set global properties for this build --> > <property name="src" value="./src"/> > <property name="build" value="./classes"/> > <property name="lucliLib" value="${build}/lucli.jar"/> > > <!-- Include all elements that Tomcat exposes to applications --> > <path id="compile.classpath"> > <fileset dir="lib"> > <include name="*.jar"/> > </fileset> > </path> > > <target name="init"> > <!-- Create the time stamp --> > <tstamp/> > <!-- Create the dist directory structure used by compile --> > <mkdir dir="${build}"/> > <mkdir dir="${build}/docs"/> > <mkdir dir="${build}/docs/javadocs"/> > </target> > > <target name="compile" depends="init"> > <!-- Compile the java code from ${src} into ${build} --> > <javac debug="on" deprecation="on" srcdir="${src}" > destdir="${build}"> > <classpath refid="compile.classpath"/> > </javac> > </target> > > <target name="build" depends="compile"> > <jar basedir="${build}" includes="**/*.class" > jarfile="${lucliLib}"/> > </target> > > > </project> > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/run.sh > > Index: run.sh > =================================================================== > LUCLI=. > LUCLI_MEMORY=128M > #JAVA_HOME=/home/dror/j2sdk1.4.1_03/ > > CLASSPATH=${CLASSPATH}:$LUCLI/lib/libreadline-java.jar:$LUCLI/lib/lucene-1.3-rc3-dev.jar:$LUCLI/classes/lucli.jar > PATH=${PATH}:$JAVA_HOME/bin > LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$LUCLI > export LD_LIBRARY_PATH > $JAVA_HOME/bin/java -Xmx${LUCLI_MEMORY} lucli.Lucli > #Use this line to enable tab completion. Depends on the Readline > shares library > #$JAVA_HOME/bin/java lucli.Lucli -r > > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/META-INF/MANIFEST.MF > > Index: MANIFEST.MF > =================================================================== > Main-Class: LuceneLine > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/lib/README > > Index: README > =================================================================== > Place libreadline-java.jar and lucene-1.3-rc3-dev.jar here. > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/src/lucli/Completer.java > > Index: Completer.java > =================================================================== > package lucli; > > /* > ==================================================================== > * The Apache Software License, Version 1.1 > * > * Copyright (c) 2001 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or > without > * modification, are permitted provided that the following > conditions > * are met: > * > * 1. Redistributions of source code must retain the above > copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above > copyright > * notice, this list of conditions and the following disclaimer > in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, > * if any, must include the following acknowledgment: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the software > itself, > * if and wherever such third-party acknowledgments normally > appear. > * > * 4. The names "Apache" and "Apache Software Foundation" and > * "Apache Lucene" must not be used to endorse or promote > products > * derived from this software without prior written permission. > For > * written permission, please contact [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be called > "Apache", > * "Apache Lucene", nor may "Apache" appear in their name, > without > * prior written permission of the Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED > AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY > OF > * SUCH DAMAGE. > * > ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For > more > * information on the Apache Software Foundation, please see > * <http://www.apache.org/>. > */ > > import org.gnu.readline.*; > import java.util.Iterator; > import java.util.TreeMap; > > /** > * Provide for tab completion > * When the user types a tab do the standard thing: complete the > command > * Two tabs show all possible completions. > */ > > > public class Completer implements ReadlineCompleter { > > String[] words; //list of words > int currentPosition = 0; //current position in the array > > /** > Default constructor. > */ > > public Completer (TreeMap wordMap) { > int size = wordMap.size(); > words = new String[size]; > Iterator wordIterator = wordMap.keySet().iterator(); > for (int ii=0; wordIterator.hasNext(); ii++) { > words[ii] = (String) wordIterator.next(); > } > } > > > /** > Return possible completion. Implements > org.gnu.readline.ReadlineCompleter. > */ > > public String completer (String text, int state) { > > String ret = null; //what we're returning > for (int ii = currentPosition; ii < words.length; ii++) { > if (words[ii].startsWith(text)) { > int next = ii + 1; > if ((next < words.length) && > words[next].startsWith(text)) { > //more than one word match > currentPosition = ii + 1; //next time start > with next one > ret = words[ii]; > break; > } else { //found the last one > if (state == 0) { //if it's the only one > ret = words[ii]; > break; > } else { > ret = null; //there were previous ones > break; > } > } > } > } > if (ret == null) > currentPosition = 0; //for next search > //System.out.println("returned:" + ret); > return (ret); //no more matches > } > } > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/src/lucli/LuceneMethods.java > > Index: LuceneMethods.java > =================================================================== > package lucli; > > /* > ==================================================================== > * The Apache Software License, Version 1.1 > * > * Copyright (c) 2001 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or > without > * modification, are permitted provided that the following > conditions > * are met: > * > * 1. Redistributions of source code must retain the above > copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above > copyright > * notice, this list of conditions and the following disclaimer > in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, > * if any, must include the following acknowledgment: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the software > itself, > * if and wherever such third-party acknowledgments normally > appear. > * > * 4. The names "Apache" and "Apache Software Foundation" and > * "Apache Lucene" must not be used to endorse or promote > products > * derived from this software without prior written permission. > For > * written permission, please contact [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be called > "Apache", > * "Apache Lucene", nor may "Apache" appear in their name, > without > * prior written permission of the Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED > AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY > OF > * SUCH DAMAGE. > * > ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For > more > * information on the Apache Software Foundation, please see > * <http://www.apache.org/>. > */ > > import java.io.IOException; > import java.io.BufferedReader; > import java.io.InputStreamReader; > import java.io.Reader; > import java.io.StringReader; > > import java.util.Hashtable; > import java.util.Vector; > import java.util.TreeMap; > import java.util.Map.Entry; > import java.util.Set; > import java.util.Arrays; > import java.util.Comparator; > import java.util.Iterator; > import java.util.Enumeration; > > import org.apache.lucene.analysis.Analyzer; > import org.apache.lucene.analysis.Token; > import org.apache.lucene.analysis.TokenStream; > import org.apache.lucene.analysis.standard.StandardAnalyzer; > import org.apache.lucene.document.Document; > import org.apache.lucene.document.Field; > import org.apache.lucene.index.IndexReader; > import org.apache.lucene.index.IndexWriter; > import org.apache.lucene.index.Term; > import org.apache.lucene.index.TermEnum; > import org.apache.lucene.queryParser.MultiFieldQueryParser; > import org.apache.lucene.queryParser.ParseException; > import org.apache.lucene.search.Explanation; > import org.apache.lucene.search.Hits; > import org.apache.lucene.search.IndexSearcher; > import org.apache.lucene.search.Query; > import org.apache.lucene.search.Searcher; > > /* > * Parts addapted from Lucene demo. Various methods that interact > with > * Lucene and provide info about the index, search, etc. > */ > class LuceneMethods { > > private int numDocs; > private String indexName; //directory of this index > private long version; //version number of this index > java.util.Iterator fieldIterator; > Vector fields; //Fields as a vector > Vector indexedFields; //Fields as a vector > String fieldsArray[]; //Fields as an array > Searcher searcher; > Query query; //current query string > > public LuceneMethods(String index) { > indexName = index; > message("Lucene CLI. Using directory:" + indexName); > } > > > public void info() throws java.io.IOException { > IndexReader indexReader = IndexReader.open(indexName); > > > getFieldInfo(); > numDocs= indexReader.numDocs(); > message("Index has " + numDocs + " documents "); > message ("All Fields:" + fields.toString()); > message ("Indexed Fields:" + indexedFields.toString()); > > if (IndexReader.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) throws java.io.IOException, > org.apache.lucene.queryParser.ParseException { > BufferedReader in = new BufferedReader(new > InputStreamReader(System.in)); > Hits hits = initSearch(queryString); > System.out.println(hits.length() + " total matching documents"); > Query explainQuery; > if (explain) { > query = explainQuery(queryString); > } > > > final int HITS_PER_PAGE = 10; > message ("--------------------------------------"); > for (int start = 0; start < hits.length(); start += > HITS_PER_PAGE) { > int end = Math.min(hits.length(), start + HITS_PER_PAGE); > for (int ii = start; ii < end; ii++) { > Document doc = hits.doc(ii); > message ("---------------- " + ii + " score:" + > hits.score(ii) > + "---------------------"); > printHit(doc); > if (showTokens) { > invertDocument(doc); > } > if (explain) { > Explanation exp = searcher.explain(query, > hits.id(ii)); > message("Explanation:" + exp.toString()); > } > } > message ("#################################################"); > > if (hits.length() > end) { > System.out.print("more (y/n) ? "); > queryString = in.readLine(); > if (queryString.length() == 0 || queryString.charAt(0) > == 'n') > break; > } > } > searcher.close(); > } > > private void printHit(Document doc) { > for (int ii= 0; ii < fieldsArray.length; ii++) { > String currField = fieldsArray[ii]; > String result = doc.get(currField); > message(currField + ":" + result); > } > //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 > StandardAnalyzer(), false); > 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); > Analyzer analyzer = new StandardAnalyzer(); > getFieldInfo(); > > BufferedReader in = new BufferedReader(new > InputStreamReader(System.in)); > > MultiFieldQueryParser parser = new > MultiFieldQueryParser(queryString, analyzer); > > int arraySize = indexedFields.size(); > String indexedArray[] = new String[arraySize]; > for (int ii = 0; ii < arraySize; ii++) { > indexedArray[ii] = (String) indexedFields.get(ii); > } > query = parser.parse(queryString, indexedArray, analyzer); > System.out.println("Searching for: " + query.toString()); > return (query); > > } > private Hits initSearch(String queryString) throws IOException, > ParseException { > > searcher = new IndexSearcher(indexName); > Analyzer analyzer = new StandardAnalyzer(); > getFieldInfo(); > > BufferedReader in = new BufferedReader(new > InputStreamReader(System.in)); > > MultiFieldQueryParser parser = new > MultiFieldQueryParser(queryString, analyzer); > > int arraySize = fields.size(); > fieldsArray = new String[arraySize]; > for (int ii = 0; ii < arraySize; ii++) { > fieldsArray[ii] = (String) fields.get(ii); > } > query = parser.parse(queryString, fieldsArray, analyzer); > System.out.println("Searching for: " + query.toString()); > Hits hits = searcher.search(query); > return (hits); > > } > > public void count(String queryString) throws java.io.IOException, > ParseException { > Hits hits = initSearch(queryString); > System.out.println(hits.length() + " total documents"); > searcher.close(); > } > > static public void message (String s) { > System.out.println(s); > } > > private void getFieldInfo() throws IOException { > IndexReader indexReader = IndexReader.open(indexName); > fields = new Vector(); > indexedFields = new Vector(); > > //get the list of all field names > fieldIterator = indexReader.getFieldNames().iterator(); > while (fieldIterator.hasNext()) { > Object field = fieldIterator.next(); > if (field != null && !field.equals("")) > fields.add(field.toString()); > } > // > //get the list of indexed field names > fieldIterator = indexReader.getFieldNames(true).iterator(); > while (fieldIterator.hasNext()) { > Object field = fieldIterator.next(); > 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 { > > Hashtable tokenHash = new Hashtable(); > final int maxFieldLength = 10000; > > Analyzer analyzer = new StandardAnalyzer(); > Enumeration fields = doc.fields(); > while (fields.hasMoreElements()) { > Field field = (Field) fields.nextElement(); > 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.tokenStream(fieldName, reader); > try { > for (Token t = stream.next(); t != > null; t = stream.next()) { > position += > (t.getPositionIncrement() - 1); > position++; > String name = t.termText(); > Integer Count = > (Integer)tokenHash.get(name); > if (Count == null) { // not in > there yet > tokenHash.put(name, > new Integer(1)); //first one > } else { > int count = > Count.intValue(); > tokenHash.put(name, > new Integer (count+1)); > } > if (position > maxFieldLength) > break; > } > } finally { > stream.close(); > } > } > > } > } > Entry[] sortedHash = getSortedHashtableEntries(tokenHash); > for (int ii = 0; ii < sortedHash.length && ii < 10; ii ++) { > Entry 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 termMap = new TreeMap(); > IndexReader indexReader = IndexReader.open(indexName); > TermEnum terms = indexReader.terms(); > while (terms.next()) { > Term term = terms.term(); > //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(term.field())) > termMap.put(new Integer((0 - terms.docFreq())), > term.field() + > ":" + term.text()); > } > > Iterator termIterator = termMap.keySet().iterator(); > for (int ii=0; termIterator.hasNext() && ii < 100; ii++) { > Integer termFreq = (Integer) termIterator.next(); > String termDetails = (String) termMap.get(termFreq); > message(termDetails + ": " + termFreq); > } > indexReader.close(); > } > > /** Sort Hashtable values > * @param h the hashtable we're sorting > * from > http://developer.java.sun.com/developer/qow/archive/170/index.jsp > */ > > public static Entry[] > getSortedHashtableEntries(Hashtable h) { > Set set = h.entrySet(); > Entry [] entries = > (Entry[])set.toArray( > > new Entry[set.size()]); > Arrays.sort(entries, new Comparator() { > public int compare(Object o1, Object o2) { > Object v1 = ((Entry)o1).getValue(); > Object v2 = ((Entry)o2).getValue(); > return ((Comparable)v2).compareTo(v1); > //descending order > } > }); > return entries; > } > > } > > > > > 1.1 > jakarta-lucene-sandbox/contributions/lucli/src/lucli/Lucli.java > > Index: Lucli.java > =================================================================== > package lucli; > > /* > ==================================================================== > * The Apache Software License, Version 1.1 > * > * Copyright (c) 2001 The Apache Software Foundation. All rights > * reserved. > * > * Redistribution and use in source and binary forms, with or > without > * modification, are permitted provided that the following > conditions > * are met: > * > * 1. Redistributions of source code must retain the above > copyright > * notice, this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above > copyright > * notice, this list of conditions and the following disclaimer > in > * the documentation and/or other materials provided with the > * distribution. > * > * 3. The end-user documentation included with the redistribution, > * if any, must include the following acknowledgment: > * "This product includes software developed by the > * Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the software > itself, > * if and wherever such third-party acknowledgments normally > appear. > * > * 4. The names "Apache" and "Apache Software Foundation" and > * "Apache Lucene" must not be used to endorse or promote > products > * derived from this software without prior written permission. > For > * written permission, please contact [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be called > "Apache", > * "Apache Lucene", nor may "Apache" appear in their name, > without > * prior written permission of the Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE > * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED > AND > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > OUT > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY > OF > * SUCH DAMAGE. > * > ==================================================================== > * > * This software consists of voluntary contributions made by many > * individuals on behalf of the Apache Software Foundation. For > more > * information on the Apache Software Foundation, please see > * <http://www.apache.org/>. > */ > > import java.io.*; > import org.gnu.readline.*; > import org.apache.lucene.queryParser.ParseException; > import java.util.StringTokenizer; > import java.util.TreeMap; > import java.util.Iterator; > > /** > * lucli 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"; //directory "index" > under the current 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; > > String fullPath; > TreeMap commandMap = new TreeMap(); > 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 ParseException, IOException { > String line; > > fullPath = System.getProperty("user.home") + > System.getProperty("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); > > > > //parse command line arguments > parseArgs(args); > > if (enableReadline) > org.gnu.readline.Readline.load(ReadlineLibrary.GnuReadline ); > else > org.gnu.readline.Readline.load(ReadlineLibrary.PureJava ); > > Readline.initReadline("lucli"); // init, set app name, read > inputrc > > > > Readline.readHistoryFile(fullPath); > > // read history file, if available > > File history = new File(".rltest_history"); > try { > if (history.exists()) > Readline.readHistoryFile(history.getName()); > } catch (Exception e) { > System.err.println("Error reading history file!"); > } > > // Set word break characters > try { > Readline.setWordBreakCharacters(" \t;"); > } > catch (UnsupportedEncodingException enc) { > System.err.println("Could not set word break characters"); > System.exit(0); > } > > // set completer with list of words > > Readline.setCompleter(new Completer(commandMap)); > > // main input loop > > luceneMethods = new LuceneMethods(DEFAULT_INDEX); > > while (true) { > try { > line = Readline.readline("lucli> "); > if (line != null) { > handleCommand(line); > } > } catch (UnsupportedEncodingException enc) { > System.err.println("caught > UnsupportedEncodingException"); > break; > } catch (java.io.EOFException eof) { > System.out.println("");//new line > exit(); > } catch (IOException ioe) { > throw (ioe); > } > } > > exit(); > } > > public static void main(String[] args) throws ParseException, > IOException { > new Lucli(args); > } > > > private void handleCommand(String line) throws IOException, > ParseException { > String [] words = tokenizeCommand(line); > if (words.length == 0) > return; //white space > String query = ""; > //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); > 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); > break; > case EXPLAIN: > for (int ii = 1; ii < words.length; ii++) { > query += words[ii] + " "; > } > luceneMethods.search(query, true, false); > 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() { > > try { > Readline.writeHistoryFile(fullPath); > } catch (IOException ioe) { > error("while saving history:" + ioe); > } > Readline.cleanup(); > 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.toLowerCase(); //treat uppercase and lower case commands the > same > Command 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 commands = commandMap.keySet().iterator(); > while (commands.hasNext()) { > Command 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 > * Code inspired by > http://www.ecs.umass.edu/ece/wireless/people/emmanuel/java/java/cmdLineArgs/parsing.html > */ > private void parseArgs(String[] args) { > for (int ii = 0; ii < args.length; ii++) { > // a little overkill for now, but foundation > // for other args > if (args[ii].startsWith("-")) { > String arg = args[ii]; > if (arg.equals("-r")) { > enableReadline = true; > } > else { > usage(); > System.exit(1); > } > } > } > } > > private void usage() { > message("Usage: lucli [-j]"); > message("Arguments:"); > message("\t-r: Provide tab completion and history using the GNU > readline shared library "); > } > > private class Command { > String name; > int id; > int numberArgs; > 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"); > } > > } > } > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > __________________________________ Do you Yahoo!? New Yahoo! Photos - easier uploading and sharing. http://photos.yahoo.com/ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]