mirror of https://github.com/apache/lucene.git
use jline instead of java-readline. jline can be added to SVN thanks to its BSD license. plus some small cleanup.
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@158850 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9fcd99dbda
commit
5a59714f4a
|
@ -1,2 +1,2 @@
|
|||
Main-Class: lucli.Lucli
|
||||
Class-Path: lib/libreadline-java.jar lib/lucene.jar
|
||||
Class-Path: lib/jline.jar lib/lucene.jar
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Place libreadline-java.jar.
|
|
@ -0,0 +1,33 @@
|
|||
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.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
AnyObjectId[b841cf167aa3ca6c82f2e40ba2fd8732e829525f] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,118 +0,0 @@
|
|||
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
|
||||
}
|
||||
}
|
|
@ -55,8 +55,6 @@ package lucli;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
|
@ -70,6 +68,8 @@ import java.util.Comparator;
|
|||
import java.util.Iterator;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import jline.ConsoleReader;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.Token;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
|
@ -130,15 +130,14 @@ class LuceneMethods {
|
|||
}
|
||||
|
||||
|
||||
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));
|
||||
public void search(String queryString, boolean explain, boolean showTokens, ConsoleReader cr)
|
||||
throws java.io.IOException, org.apache.lucene.queryParser.ParseException {
|
||||
Hits hits = initSearch(queryString);
|
||||
System.out.println(hits.length() + " total matching documents");
|
||||
if (explain) {
|
||||
query = explainQuery(queryString);
|
||||
}
|
||||
|
||||
|
||||
final int HITS_PER_PAGE = 10;
|
||||
message("--------------------------------------");
|
||||
for (int start = 0; start < hits.length(); start += HITS_PER_PAGE) {
|
||||
|
@ -158,8 +157,8 @@ class LuceneMethods {
|
|||
message("#################################################");
|
||||
|
||||
if (hits.length() > end) {
|
||||
System.out.print("more (y/n) ? ");
|
||||
queryString = in.readLine();
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -54,18 +54,27 @@ package lucli;
|
|||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import org.gnu.readline.*;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
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 java.util.Iterator;
|
||||
|
||||
import jline.ArgumentCompletor;
|
||||
import jline.Completor;
|
||||
import jline.ConsoleReader;
|
||||
import jline.FileNameCompletor;
|
||||
import jline.History;
|
||||
import jline.SimpleCompletor;
|
||||
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
|
||||
/**
|
||||
* lucli Main class for lucli: the Lucene Command Line Interface
|
||||
* 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
|
||||
|
@ -87,7 +96,7 @@ public class Lucli {
|
|||
final static int TOKENS = 8;
|
||||
final static int EXPLAIN = 9;
|
||||
|
||||
String fullPath;
|
||||
String historyFile;
|
||||
TreeMap commandMap = new TreeMap();
|
||||
LuceneMethods luceneMethods; //current cli class we're using
|
||||
boolean enableReadline; //false: use plain java. True: shared library readline
|
||||
|
@ -97,16 +106,14 @@ public class Lucli {
|
|||
application initialization file.
|
||||
*/
|
||||
|
||||
public Lucli(String[] args) throws ParseException, IOException {
|
||||
public Lucli(String[] args) throws IOException {
|
||||
String line;
|
||||
|
||||
fullPath = System.getProperty("user.home") + System.getProperty("file.separator")
|
||||
+ HISTORYFILE;
|
||||
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);
|
||||
|
@ -118,79 +125,64 @@ public class Lucli {
|
|||
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);
|
||||
}
|
||||
|
||||
ConsoleReader cr = new ConsoleReader();
|
||||
//Readline.readHistoryFile(fullPath);
|
||||
cr.setHistory(new History(new File(historyFile)));
|
||||
|
||||
// set completer with list of words
|
||||
|
||||
Readline.setCompleter(new Completer(commandMap));
|
||||
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 = Readline.readline("lucli> ");
|
||||
line = cr.readLine("lucli> ");
|
||||
if (line != null) {
|
||||
handleCommand(line);
|
||||
handleCommand(line, cr);
|
||||
}
|
||||
} catch (UnsupportedEncodingException enc) {
|
||||
System.err.println("caught UnsupportedEncodingException");
|
||||
break;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ParseException, IOException {
|
||||
private String[] getCommandsAsArray() {
|
||||
Set commandSet = commandMap.keySet();
|
||||
String[] commands = new String[commandMap.size()];
|
||||
int i = 0;
|
||||
for (Iterator iter = commandSet.iterator(); iter.hasNext();) {
|
||||
String cmd = (String) iter.next();
|
||||
commands[i++] = cmd;
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
new Lucli(args);
|
||||
}
|
||||
|
||||
|
||||
private void handleCommand(String line) throws IOException, ParseException {
|
||||
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:
|
||||
|
@ -200,7 +192,7 @@ public class Lucli {
|
|||
for (int ii = 1; ii < words.length; ii++) {
|
||||
query += words[ii] + " ";
|
||||
}
|
||||
luceneMethods.search(query, false, false);
|
||||
luceneMethods.search(query, false, false, cr);
|
||||
break;
|
||||
case COUNT:
|
||||
for (int ii = 1; ii < words.length; ii++) {
|
||||
|
@ -234,13 +226,13 @@ public class Lucli {
|
|||
for (int ii = 1; ii < words.length; ii++) {
|
||||
query += words[ii] + " ";
|
||||
}
|
||||
luceneMethods.search(query, false, true);
|
||||
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);
|
||||
luceneMethods.search(query, true, false, cr);
|
||||
break;
|
||||
case HELP:
|
||||
help();
|
||||
|
@ -248,7 +240,7 @@ public class Lucli {
|
|||
case NOCOMMAND: //do nothing
|
||||
break;
|
||||
case UNKOWN:
|
||||
System.out.println("Unknown command:" + words[0] + ". Type help to get a list of commands.");
|
||||
System.out.println("Unknown command: " + words[0] + ". Type help to get a list of commands.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -264,13 +256,6 @@ public class Lucli {
|
|||
}
|
||||
|
||||
private void exit() {
|
||||
|
||||
try {
|
||||
Readline.writeHistoryFile(fullPath);
|
||||
} catch (IOException ioe) {
|
||||
error("while saving history:" + ioe);
|
||||
}
|
||||
Readline.cleanup();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
@ -329,32 +314,19 @@ public class Lucli {
|
|||
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
|
||||
* Parse command line arguments (currently none)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (args.length > 0) {
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void usage() {
|
||||
message("Usage: lucli [-r]");
|
||||
message("Arguments:");
|
||||
message("\t-r: Provide tab completion and history using the GNU readline shared library ");
|
||||
message("Usage: lucli.Lucli");
|
||||
message("(currently, no parameters are supported)");
|
||||
}
|
||||
|
||||
private class Command {
|
||||
|
|
Loading…
Reference in New Issue