lucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ehatc...@apache.org
Subject cvs commit: jakarta-lucene-sandbox/contributions/lucli/src/lucli Completer.java LuceneMethods.java Lucli.java
Date Thu, 11 Dec 2003 02:07:46 GMT
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
  dror@zapatec.com.
  
  
  
  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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Lucene", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Lucene", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Lucene", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <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: lucene-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: lucene-dev-help@jakarta.apache.org


Mime
View raw message