More updates to the blur-shell.

Project: http://git-wip-us.apache.org/repos/asf/incubator-blur/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-blur/commit/fdb5f48a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-blur/tree/fdb5f48a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-blur/diff/fdb5f48a

Branch: refs/heads/0.2-dev
Commit: fdb5f48aa0fd62fad808bdf302845457e12d3ea2
Parents: 287c44c
Author: Aaron McCurry <[email protected]>
Authored: Sun Jan 6 18:18:49 2013 -0500
Committer: Aaron McCurry <[email protected]>
Committed: Sun Jan 6 18:18:49 2013 -0500

----------------------------------------------------------------------
 src/blur-shell/pom.xml                             |    2 +-
 src/blur-shell/src/assemble/bin.xml                |    8 +
 .../java/org/apache/blur/shell/AddCommand.java     |    2 +-
 .../src/main/java/org/apache/blur/shell/Main.java  |    7 +-
 .../java/org/apache/blur/shell/SearchCommand.java  |  109 +++++---
 .../blur/shell/ShowDiffsOnlyCompletionHandler.java |  201 +++++++++++++++
 .../java/org/apache/blur/thrift/LongField.java     |   92 +++++++
 7 files changed, 370 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/pom.xml
----------------------------------------------------------------------
diff --git a/src/blur-shell/pom.xml b/src/blur-shell/pom.xml
index 3847eb8..6ac95a2 100644
--- a/src/blur-shell/pom.xml
+++ b/src/blur-shell/pom.xml
@@ -83,7 +83,7 @@ under the License.
        </repositories>
 
     <build>
-        <finalName>blur-shell</finalName>
+        <finalName>blur-shell-${project.version}</finalName>
 
         <plugins>
                  <plugin>

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/src/assemble/bin.xml
----------------------------------------------------------------------
diff --git a/src/blur-shell/src/assemble/bin.xml 
b/src/blur-shell/src/assemble/bin.xml
new file mode 100644
index 0000000..463fdbc
--- /dev/null
+++ b/src/blur-shell/src/assemble/bin.xml
@@ -0,0 +1,8 @@
+<assembly 
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
 http://maven.apache.org/xsd/assembly-1.1.2.xsd";>
+  <id>bin</id>
+  <formats>
+    <format>jar</format>
+  </formats>
+</assembly>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/src/main/java/org/apache/blur/shell/AddCommand.java
----------------------------------------------------------------------
diff --git a/src/blur-shell/src/main/java/org/apache/blur/shell/AddCommand.java 
b/src/blur-shell/src/main/java/org/apache/blur/shell/AddCommand.java
index e960eb7..dbde107 100644
--- a/src/blur-shell/src/main/java/org/apache/blur/shell/AddCommand.java
+++ b/src/blur-shell/src/main/java/org/apache/blur/shell/AddCommand.java
@@ -40,7 +40,7 @@ import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
 import org.apache.thrift.TException;
 
-public class AddCommand extends Command {
+public class AddCommand extends TableSingleArgumentCommand {
   private static final String HELP = "help";
   private static final String WAL = "wal";
   private static final String VISIBLE = "visible";

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/src/main/java/org/apache/blur/shell/Main.java
----------------------------------------------------------------------
diff --git a/src/blur-shell/src/main/java/org/apache/blur/shell/Main.java 
b/src/blur-shell/src/main/java/org/apache/blur/shell/Main.java
index e5694c4..d250d2f 100644
--- a/src/blur-shell/src/main/java/org/apache/blur/shell/Main.java
+++ b/src/blur-shell/src/main/java/org/apache/blur/shell/Main.java
@@ -175,12 +175,7 @@ public class Main {
       // reader.addCompleter(new StringsCompleter(commands.keySet()));
       // reader.addCompleter(new FileNameCompleter());
 
-//      reader.setCompletionHandler(new CompletionHandler() {
-//        @Override
-//        public boolean complete(ConsoleReader reader, List<CharSequence> 
candidates, int position) throws IOException {
-//          return false;
-//        }
-//      });
+      reader.setCompletionHandler(new ShowDiffsOnlyCompletionHandler());
 
       for (Completer c : commands.values()) {
         System.out.println("adding " + c + " " + reader.addCompleter(c));

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/src/main/java/org/apache/blur/shell/SearchCommand.java
----------------------------------------------------------------------
diff --git 
a/src/blur-shell/src/main/java/org/apache/blur/shell/SearchCommand.java 
b/src/blur-shell/src/main/java/org/apache/blur/shell/SearchCommand.java
index 2008cf5..842d238 100644
--- a/src/blur-shell/src/main/java/org/apache/blur/shell/SearchCommand.java
+++ b/src/blur-shell/src/main/java/org/apache/blur/shell/SearchCommand.java
@@ -28,6 +28,7 @@ import jline.Terminal;
 import jline.console.ConsoleReader;
 
 import org.apache.blur.thrift.BlurClient;
+import org.apache.blur.thrift.LongField;
 import org.apache.blur.thrift.StringField;
 import org.apache.blur.thrift.TextField;
 import org.apache.blur.thrift.generated.Blur.Iface;
@@ -55,7 +56,7 @@ public class SearchCommand extends TableSingleArgumentCommand 
{
   private static final String HELP = "help";
   private static final String BOOST = "boost";
   private static final String FIELD = "field";
-  private static final String TYPE = "type";
+  private static final String TYPE_STR = "type";
 
   public static void main(String[] args) throws BlurException, 
CommandException, TException, ParseException {
     Iface client = BlurClient.getClient("127.0.0.1:40020");
@@ -81,7 +82,7 @@ public class SearchCommand extends TableSingleArgumentCommand 
{
     Options options = new Options();
     options.addOption("h", HELP, false, "Print the help for this command.");
     options.addOption("f", FIELD, true, "Fields to fetch during retrieval.");
-    options.addOption("t", TYPE, false, "Show field type.");
+    options.addOption("t", TYPE_STR, false, "Show field type.");
     options.addOption("b", BOOST, false, "Show field boost.");
     options.addOption("l", DOCLOC, false, "Show document locations.");
 
@@ -101,7 +102,7 @@ public class SearchCommand extends 
TableSingleArgumentCommand {
     }
 
     boolean showBoost = line.hasOption(BOOST);
-    boolean showType = line.hasOption(TYPE);
+    boolean showType = line.hasOption(TYPE_STR);
     boolean showDocLocations = line.hasOption(DOCLOC);
     String[] fieldNames = line.getOptionValues(FIELD);
 
@@ -158,8 +159,16 @@ public class SearchCommand extends 
TableSingleArgumentCommand {
   private void print(List<Document> docs, List<Long> docLocations, boolean 
showDocLocations, boolean showBoost, boolean showType, PrintWriter out, int 
maxLineWidth) {
     List<String> fieldNames = new ArrayList<String>();
     List<String> fieldTypes = new ArrayList<String>();
-    for (Document document : docs) {
+    for (int d = 0; d < docs.size(); d++) {
+      Document document = docs.get(d);
       List<Field> fields = document.getFields();
+      if (showDocLocations) {
+        List<Field> newFields = new ArrayList<Field>();
+        newFields.add(new LongField("docLocation", docLocations.get(d)));
+        newFields.addAll(fields);
+        fields = newFields;
+        document.setFields(fields);
+      }
       for (Field field : fields) {
         String name = field.getName();
         String type = field.getType().name();
@@ -177,53 +186,64 @@ public class SearchCommand extends 
TableSingleArgumentCommand {
     int typeNameWidth = maxLength(fieldTypes);
     int fieldSep = 3;
     int valueMaxWidth;
-    int metaDataWidth;
-
-    if (showBoost && showType) {
-      metaDataWidth = maxFieldNameLength + boostWidth + typeNameWidth + 
(fieldSep * 3);
-    } else if (showBoost) {
-      metaDataWidth = maxFieldNameLength + boostWidth + (fieldSep * 2);
-    } else if (showType) {
-      metaDataWidth = maxFieldNameLength + typeNameWidth + (fieldSep * 2);
-    } else {
-      metaDataWidth = maxFieldNameLength + fieldSep;
+    int metaDataWidth = maxFieldNameLength + fieldSep;
+
+    if (showBoost) {
+      metaDataWidth += boostWidth + fieldSep;
+    }
+    if (showType) {
+      metaDataWidth += typeNameWidth + fieldSep;
     }
     valueMaxWidth = maxLineWidth - metaDataWidth;
     int fieldPaging = metaDataWidth - fieldSep;
-    for (Document document : docs) {
+    for (int d = 0; d < docs.size(); d++) {
+      Document document = docs.get(d);
       for (int i = 0; i < maxLineWidth; i++) {
         out.print('-');
       }
       out.println();
-      for (Field field : document.getFields()) {
-        String name = field.getName();
-        double boost = field.getBoost();
-        TYPE type = field.getType();
-        String typeStr = type.name();
-
-        String valueStr = toString(field);
-
-        for (int i = 0; i < valueStr.length(); i += valueMaxWidth) {
-          int max = Math.min(i + valueMaxWidth, valueStr.length());
-          String displayValue = valueStr.substring(i, max);
-          if (i == 0) {
-            if (showBoost && showType) {
-              out.printf("%" + maxFieldNameLength + "s | %" + boostWidth + 
".2f | %" + typeNameWidth + "s | %." + valueMaxWidth + "s%n", name, boost, 
typeStr, displayValue);
-            } else if (showBoost) {
-              out.printf("%" + maxFieldNameLength + "s | %" + boostWidth + 
".2f | %." + valueMaxWidth + "s%n", name, boost, displayValue);
-            } else if (showType) {
-              out.printf("%" + maxFieldNameLength + "s | %" + typeNameWidth + 
"s | %." + valueMaxWidth + "s%n", name, typeStr, displayValue);
-            } else {
-              out.printf("%" + maxFieldNameLength + "s | %." + valueMaxWidth + 
"s%n", name, displayValue);
-            }
-          } else {
-            for (int c = 0; c < fieldPaging; c++) {
-              out.print(' ');
-            }
-            out.print(" | ");
-            out.println(displayValue);
-          }
+      List<Field> fields = document.getFields();
+      for (Field field : fields) {
+        printField(showBoost, showType, out, maxFieldNameLength, boostWidth, 
typeNameWidth, valueMaxWidth, fieldPaging, field);
+      }
+    }
+  }
+
+  private void printField(boolean showBoost, boolean showType, PrintWriter 
out, int maxFieldNameLength, int boostWidth, int typeNameWidth, int 
valueMaxWidth, int fieldPaging,
+      Field field) {
+    String name = field.getName();
+    double boost = field.getBoost();
+    TYPE type = field.getType();
+    String typeStr = type.name();
+
+    String valueStr = toString(field);
+
+    for (int i = 0; i < valueStr.length(); i += valueMaxWidth) {
+      int max = Math.min(i + valueMaxWidth, valueStr.length());
+      String displayValue = valueStr.substring(i, max);
+
+      if (i == 0) {
+        List<Object> args = new ArrayList<Object>();
+        String formatString = "%" + maxFieldNameLength + "s | ";
+        args.add(name);
+        if (showBoost) {
+          formatString += "%" + boostWidth + ".2f | ";
+          args.add(boost);
+        }
+        if (showType) {
+          formatString += "%" + typeNameWidth + "s | ";
+          args.add(typeStr);
+        }
+        formatString += "%." + valueMaxWidth + "s%n";
+        args.add(displayValue);
+
+        out.printf(formatString, args.toArray(new Object[] {}));
+      } else {
+        for (int c = 0; c < fieldPaging; c++) {
+          out.print(' ');
         }
+        out.print(" | ");
+        out.println(displayValue);
       }
     }
   }
@@ -239,6 +259,9 @@ public class SearchCommand extends 
TableSingleArgumentCommand {
       return new TextField(field).getValueString();
     case STRING:
       return new StringField(field).getValueString();
+    case LONG:
+      Long valueLong = new LongField(field).getValueLong();
+      return valueLong == null ? "NULL" : valueLong.toString();
     default:
       throw new RuntimeException("Not supported");
     }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-shell/src/main/java/org/apache/blur/shell/ShowDiffsOnlyCompletionHandler.java
----------------------------------------------------------------------
diff --git 
a/src/blur-shell/src/main/java/org/apache/blur/shell/ShowDiffsOnlyCompletionHandler.java
 
b/src/blur-shell/src/main/java/org/apache/blur/shell/ShowDiffsOnlyCompletionHandler.java
new file mode 100644
index 0000000..96a0799
--- /dev/null
+++ 
b/src/blur-shell/src/main/java/org/apache/blur/shell/ShowDiffsOnlyCompletionHandler.java
@@ -0,0 +1,201 @@
+package org.apache.blur.shell;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import jline.console.ConsoleReader;
+import jline.console.CursorBuffer;
+import jline.console.completer.CandidateListCompletionHandler;
+import jline.console.completer.CompletionHandler;
+
+public class ShowDiffsOnlyCompletionHandler implements CompletionHandler {
+
+  public static void main(String[] args) throws IOException {
+    ConsoleReader reader = new ConsoleReader();
+    reader.setPrompt("test> ");
+    ShowDiffsOnlyCompletionHandler handler = new 
ShowDiffsOnlyCompletionHandler();
+    reader.setCompletionHandler(handler);
+
+    String line;
+    PrintWriter out = new PrintWriter(reader.getOutput());
+    while ((line = reader.readLine()) != null) {
+      line = line.trim();
+      // ignore empty lines and comments
+      if (line.length() == 0 || line.startsWith("#")) {
+        continue;
+      }
+      out.println("output:" + line);
+    }
+  }
+
+  public boolean complete(final ConsoleReader reader, final List<CharSequence> 
candidates, final int pos) throws IOException {
+    CursorBuffer buf = reader.getCursorBuffer();
+
+    // if there is only one completion, then fill in the buffer
+    if (candidates.size() == 1) {
+      CharSequence value = candidates.get(0);
+
+      // fail if the only candidate is the same as the current buffer
+      if (value.equals(buf.toString())) {
+        return false;
+      }
+
+      setBuffer(reader, value, pos);
+
+      return true;
+    } else if (candidates.size() > 1) {
+      String value = getUnambiguousCompletions(candidates);
+      setBuffer(reader, value, pos);
+    }
+
+    printCandidates(reader, removeLeadingValues(buf.toString(), candidates));
+
+    // redraw the current console buffer
+    reader.drawLine();
+
+    return true;
+  }
+
+  private Collection<CharSequence> removeLeadingValues(String buf, 
List<CharSequence> candidates) {
+    int index = buf.lastIndexOf(' ');
+    if (index < 0) {
+      return candidates;
+    }
+    List<CharSequence> result = new ArrayList<CharSequence>();
+    String prefix = buf.substring(0, index);
+    for (CharSequence c : candidates) {
+      String s = c.toString();
+      if (s.startsWith(prefix)) {
+        result.add(s.substring(index + 1));
+      } else {
+        result.add(s);
+      }
+    }
+    return result;
+  }
+
+  public static void setBuffer(final ConsoleReader reader, final CharSequence 
value, final int offset) throws IOException {
+    while ((reader.getCursorBuffer().cursor > offset) && reader.backspace()) {
+      // empty
+    }
+
+    reader.putString(value);
+    reader.setCursorPosition(offset + value.length());
+  }
+
+  /**
+   * Print out the candidates. If the size of the candidates is greater than 
the
+   * {@link ConsoleReader#getAutoprintThreshold}, they prompt with a warning.
+   * 
+   * @param candidates
+   *          the list of candidates to print
+   */
+  public static void printCandidates(final ConsoleReader reader, 
Collection<CharSequence> candidates) throws IOException {
+    Set<CharSequence> distinct = new HashSet<CharSequence>(candidates);
+
+    if (distinct.size() > reader.getAutoprintThreshold()) {
+      // noinspection StringConcatenation
+      reader.print(Messages.DISPLAY_CANDIDATES.format(candidates.size()));
+      reader.flush();
+
+      int c;
+
+      String noOpt = Messages.DISPLAY_CANDIDATES_NO.format();
+      String yesOpt = Messages.DISPLAY_CANDIDATES_YES.format();
+      char[] allowed = { yesOpt.charAt(0), noOpt.charAt(0) };
+
+      while ((c = reader.readCharacter(allowed)) != -1) {
+        String tmp = new String(new char[] { (char) c });
+
+        if (noOpt.startsWith(tmp)) {
+          reader.println();
+          return;
+        } else if (yesOpt.startsWith(tmp)) {
+          break;
+        } else {
+          reader.beep();
+        }
+      }
+    }
+
+    // copy the values and make them distinct, without otherwise affecting the
+    // ordering. Only do it if the sizes differ.
+    if (distinct.size() != candidates.size()) {
+      Collection<CharSequence> copy = new ArrayList<CharSequence>();
+
+      for (CharSequence next : candidates) {
+        if (!copy.contains(next)) {
+          copy.add(next);
+        }
+      }
+
+      candidates = copy;
+    }
+
+    reader.println();
+    reader.printColumns(candidates);
+  }
+
+  /**
+   * Returns a root that matches all the {@link String} elements of the
+   * specified {@link List}, or null if there are no commonalities. For 
example,
+   * if the list contains <i>foobar</i>, <i>foobaz</i>, <i>foobuz</i>, the
+   * method will return <i>foob</i>.
+   */
+  private String getUnambiguousCompletions(final List<CharSequence> 
candidates) {
+    if (candidates == null || candidates.isEmpty()) {
+      return null;
+    }
+
+    // convert to an array for speed
+    String[] strings = candidates.toArray(new String[candidates.size()]);
+
+    String first = strings[0];
+    StringBuilder candidate = new StringBuilder();
+
+    for (int i = 0; i < first.length(); i++) {
+      if (startsWith(first.substring(0, i + 1), strings)) {
+        candidate.append(first.charAt(i));
+      } else {
+        break;
+      }
+    }
+
+    return candidate.toString();
+  }
+
+  /**
+   * @return true is all the elements of <i>candidates</i> start with
+   *         <i>starts</i>
+   */
+  private boolean startsWith(final String starts, final String[] candidates) {
+    for (String candidate : candidates) {
+      if (!candidate.startsWith(starts)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private static enum Messages {
+    DISPLAY_CANDIDATES, DISPLAY_CANDIDATES_YES, DISPLAY_CANDIDATES_NO, ;
+
+    private static final ResourceBundle bundle = 
ResourceBundle.getBundle(CandidateListCompletionHandler.class.getName(), 
Locale.getDefault());
+
+    public String format(final Object... args) {
+      if (bundle == null)
+        return "";
+      else
+        return String.format(bundle.getString(name()), args);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/fdb5f48a/src/blur-thrift/src/main/java/org/apache/blur/thrift/LongField.java
----------------------------------------------------------------------
diff --git 
a/src/blur-thrift/src/main/java/org/apache/blur/thrift/LongField.java 
b/src/blur-thrift/src/main/java/org/apache/blur/thrift/LongField.java
new file mode 100644
index 0000000..605f128
--- /dev/null
+++ b/src/blur-thrift/src/main/java/org/apache/blur/thrift/LongField.java
@@ -0,0 +1,92 @@
+package org.apache.blur.thrift;
+
+import java.nio.ByteBuffer;
+
+import org.apache.blur.thrift.generated.Field;
+import org.apache.blur.thrift.generated.TYPE;
+
+@SuppressWarnings("serial")
+public class LongField extends Field {
+
+  public LongField(String name, Long value) {
+    super(name, toByteBuffer(value), TYPE.LONG, 1.0);
+  }
+  
+  public static void main(String[] args) {
+    LongField longField = new LongField("a", 1l);
+    System.out.println(longField.getValueLong());
+  }
+
+  private static ByteBuffer toByteBuffer(Long value) {
+    if (value == null) {
+      return null;
+    }
+    ByteBuffer buffer = ByteBuffer.allocate(8).putLong(value);
+    buffer.flip();
+    return buffer;
+  }
+
+  public LongField() {
+
+  }
+
+  public LongField(Field field) {
+    super(field.name, field.value, field.type, field.boost);
+    if (field.getType() != TYPE.LONG) {
+      throw new RuntimeException("Field [" + field + "] is not of type Long.");
+    }
+  }
+
+  public Long getValueLong() {
+    byte[] bs = getValue();
+    if (bs == null) {
+      return null;
+    }
+    return ByteBuffer.wrap(bs).getLong();
+  }
+
+  public LongField setValueLong(Long value) {
+    setValue(toByteBuffer(value));
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("LongField(");
+    boolean first = true;
+
+    sb.append("name:");
+    if (this.name == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.name);
+    }
+    first = false;
+    if (!first)
+      sb.append(", ");
+    sb.append("value:");
+    if (this.value == null) {
+      sb.append("null");
+    } else {
+      sb.append(getValueLong());
+    }
+    first = false;
+    if (!first)
+      sb.append(", ");
+    sb.append("type:");
+    if (this.type == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.type);
+    }
+    first = false;
+    if (!first)
+      sb.append(", ");
+    sb.append("boost:");
+    sb.append(this.boost);
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+}

Reply via email to