accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ktur...@apache.org
Subject svn commit: r1376213 - in /accumulo/trunk/core/src: main/java/org/apache/accumulo/core/conf/ main/java/org/apache/accumulo/core/util/format/ main/java/org/apache/accumulo/core/util/interpret/ main/java/org/apache/accumulo/core/util/shell/ main/java/org...
Date Wed, 22 Aug 2012 19:55:44 GMT
Author: kturner
Date: Wed Aug 22 19:55:43 2012
New Revision: 1376213

URL: http://svn.apache.org/viewvc?rev=1376213&view=rev
Log:
ACCUMULO-735 added hooks for translating shell's scan range and column arguments

Added:
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
Modified:
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
    accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
    accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java (original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java Wed Aug
22 19:55:43 2012
@@ -21,6 +21,8 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.accumulo.core.file.rfile.RFile;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
 import org.apache.accumulo.start.classloader.AccumuloClassLoader;
 
 public enum Property {
@@ -281,8 +283,10 @@ public enum Property {
           + "For example table.group.group1=x,y,z sets the column families for a group called
group1. Once configured, "
           + "group1 can be enabled by adding it to the list of groups in the " + TABLE_LOCALITY_GROUPS.getKey()
+ " property.<br />"
           + "Additional group options may be specified for a named group by setting table.group.&lt;name&gt;.opt.&lt;key&gt;=&lt;value&gt;."),
-  TABLE_FORMATTER_CLASS("table.formatter", "org.apache.accumulo.core.util.format.DefaultFormatter",
PropertyType.STRING,
-      "The Formatter class to apply on results in the shell");
+  TABLE_FORMATTER_CLASS("table.formatter", DefaultFormatter.class.getName(), PropertyType.STRING,
+      "The Formatter class to apply on results in the shell"),
+  TABLE_INTERPRETER_CLASS("table.interepreter", DefaultScanInterpreter.class.getName(), PropertyType.STRING,
+      "The ScanInterpreter class to apply on scan arguments in the shell");
   
   private String key, defaultValue, description;
   private PropertyType type;

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
Wed Aug 22 19:55:43 2012
@@ -21,11 +21,13 @@ import java.util.Map.Entry;
 
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.hadoop.io.Text;
 
 /**
  * A simple formatter that print the row, column family, column qualifier, and value as hex
  */
-public class HexFormatter implements Formatter {
+public class HexFormatter implements Formatter, ScanInterpreter {
   
   private char chars[] = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
'b', 'c', 'd', 'e', 'f'};
   private Iterator<Entry<Key,Value>> iter;
@@ -40,6 +42,33 @@ public class HexFormatter implements For
       sb.append(chars[0x0f & bin[i]]);
     }
   }
+  
+  private int fromChar(char b) {
+    if (b >= '0' && b <= '9') {
+      return (b - '0');
+    } else if (b >= 'a' && b <= 'f') {
+      return (b - 'a' + 10);
+    }
+    
+    throw new IllegalArgumentException("Bad char " + b);
+  }
+  
+  private byte[] toBinary(String hex) {
+    hex = hex.replace("-", "");
+
+    byte[] bin = new byte[(hex.length() / 2) + (hex.length() % 2)];
+    
+    int j = 0;
+    for (int i = 0; i < bin.length; i++) {
+      bin[i] = (byte) (fromChar(hex.charAt(j++)) << 4);
+      if (j >= hex.length())
+        break;
+      bin[i] |= (byte) fromChar(hex.charAt(j++));
+    }
+    
+    return bin;
+  }
+
 
   @Override
   public boolean hasNext() {
@@ -80,4 +109,28 @@ public class HexFormatter implements For
     this.printTimestamps = printTimestamps;
   }
   
+  @Override
+  public Text interpretRow(Text row) {
+    return new Text(toBinary(row.toString()));
+  }
+  
+  @Override
+  public Text interpretBeginRow(Text row) {
+    return new Text(toBinary(row.toString()));
+  }
+
+  @Override
+  public Text interpretEndRow(Text row) {
+    return new Text(toBinary(row.toString()));
+  }
+
+  @Override
+  public Text interpretColumnFamily(Text cf) {
+    return new Text(toBinary(cf.toString()));
+  }
+
+  @Override
+  public Text interpretColumnQualifier(Text cq) {
+    return new Text(toBinary(cq.toString()));
+  }
 }

Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java?rev=1376213&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
(added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.interpret;
+
+import org.apache.hadoop.io.Text;
+
+/**
+ * 
+ */
+public class DefaultScanInterpreter implements ScanInterpreter {
+  
+  @Override
+  public Text interpretRow(Text row) {
+    return row;
+  }
+  
+  @Override
+  public Text interpretBeginRow(Text row) {
+    return row;
+  }
+  
+  @Override
+  public Text interpretEndRow(Text row) {
+    return row;
+  }
+  
+  @Override
+  public Text interpretColumnFamily(Text cf) {
+    return cf;
+  }
+  
+  @Override
+  public Text interpretColumnQualifier(Text cq) {
+    return cq;
+  }
+  
+}

Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java?rev=1376213&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
(added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.interpret;
+
+import org.apache.accumulo.core.util.format.HexFormatter;
+
+/**
+ * As simple scan interpreter that converts hex to binary. IT supports translating the output
of {@link HexFormatter} back to binary. The hex input can contain
+ * dashes (because {@link HexFormatter} outputs dashes) which are ignored.
+ */
+public class HexScanInterpreter extends HexFormatter implements ScanInterpreter {
+  
+}

Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java?rev=1376213&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
(added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.interpret;
+
+import org.apache.hadoop.io.Text;
+
+/**
+ * A simple interface for creating shell plugins that translate the range and column arguments
for the shell's scan command.
+ */
+public interface ScanInterpreter {
+  
+  public Text interpretRow(Text row);
+
+  public Text interpretBeginRow(Text row);
+  
+  public Text interpretEndRow(Text row);
+  
+  public Text interpretColumnFamily(Text cf);
+  
+  public Text interpretColumnQualifier(Text cq);
+}

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java (original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java Wed Aug
22 19:55:43 2012
@@ -103,6 +103,7 @@ import org.apache.accumulo.core.util.she
 import org.apache.accumulo.core.util.shell.commands.ImportTableCommand;
 import org.apache.accumulo.core.util.shell.commands.InfoCommand;
 import org.apache.accumulo.core.util.shell.commands.InsertCommand;
+import org.apache.accumulo.core.util.shell.commands.InterpreterCommand;
 import org.apache.accumulo.core.util.shell.commands.ListIterCommand;
 import org.apache.accumulo.core.util.shell.commands.ListScansCommand;
 import org.apache.accumulo.core.util.shell.commands.MaxRowCommand;
@@ -291,7 +292,7 @@ public class Shell extends ShellOptions 
     rootToken = new Token();
     
     Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(), new DeleteRowsCommand(),
new EGrepCommand(), new FormatterCommand(),
-        new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(),
new ScanCommand()};
+        new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(),
new MaxRowCommand(), new ScanCommand()};
     Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(),
new TraceCommand()};
     Command[] execCommands = {new ExecfileCommand(), new HistoryCommand()};
     Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
@@ -812,12 +813,6 @@ public class Shell extends ShellOptions 
     }
   }
   
-  public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean
printTimestamps, boolean paginate) throws IOException {
-    Class<? extends Formatter> formatterClass = getFormatter();
-    
-    printRecords(scanner, printTimestamps, paginate, formatterClass);
-  }
-  
   public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean
printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
       throws IOException {
     printLines(FormatterFactory.getFormatter(formatterClass, scanner, printTimestamps), paginate);

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,30 +16,26 @@
  */
 package org.apache.accumulo.core.util.shell.commands;
 
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.BatchWriter;
 import org.apache.accumulo.core.client.IteratorSetting;
 import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.iterators.SortedKeyIterator;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.format.DeleterFormatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
 import org.apache.accumulo.core.util.shell.Shell;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
 
 public class DeleteManyCommand extends ScanCommand {
   private Option forceOpt;
   
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException,
AccumuloSecurityException, TableNotFoundException,
-      IOException, ParseException {
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
     String tableName = OptUtil.getTableOpt(cl, shellState);
     
+    ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
     // handle first argument, if present, the authorizations list to
     // scan with
     Authorizations auths = getAuths(cl, shellState);
@@ -48,10 +44,10 @@ public class DeleteManyCommand extends S
     scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
     
     // handle remaining optional arguments
-    scanner.setRange(getRange(cl));
+    scanner.setRange(getRange(cl, interpeter));
     
     // handle columns
-    fetchColumns(cl, scanner);
+    fetchColumns(cl, scanner, interpeter);
     
     // output / delete the records
     BatchWriter writer = shellState.getConnector().createBatchWriter(tableName, 1024 * 1024,
1000L, 4);

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,114 +16,52 @@
  */
 package org.apache.accumulo.core.util.shell.commands;
 
-import java.util.Iterator;
-import java.util.Map.Entry;
-
 import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.util.format.Formatter;
 import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.AccumuloClassLoader;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 
-public class FormatterCommand extends Command {
-  private Option removeFormatterOption, formatterClassOption, listClassOption;
+public class FormatterCommand extends ShellPluginConfigurationCommand {
   
+  private Option interpeterOption;
+
+  public FormatterCommand() {
+    super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
+  }
+
   @Override
   public String description() {
     return "specifies a formatter to use for displaying table entries";
   }
-  
-  @Override
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
-    String tableName = OptUtil.getTableOpt(cl, shellState);
-    
-    if (cl.hasOption(removeFormatterOption.getOpt())) {
-      // Remove the property
-      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString());
-      
-      shellState.getReader().printString("Removed formatter on " + tableName + "\n");
-    } else if (cl.hasOption(listClassOption.getOpt())) {
-      // Get the options for this table
-      Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-      
-      while (iter.hasNext()) {
-        Entry<String,String> ent = iter.next();
-        
-        // List all parameters with the property name
-        if (ent.getKey().startsWith(Property.TABLE_FORMATTER_CLASS.toString())) {
-          shellState.getReader().printString(ent.getKey() + ": " + ent.getValue() + "\n");
-        }
-      }
-    } else {
-      // Set the formatter with the provided options
-      String className = cl.getOptionValue(formatterClassOption.getOpt());
-      
-      // Set the formatter property on the table
-      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(),
className);
-    }
-    
-    return 0;
-  }
-  
+
   public static Class<? extends Formatter> getCurrentFormatter(String tableName, Shell
shellState) {
-    Iterator<Entry<String,String>> props;
-    try {
-      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-    } catch (AccumuloException e) {
-      return null;
-    } catch (TableNotFoundException e) {
-      return null;
-    }
-    
-    while (props.hasNext()) {
-      Entry<String,String> ent = props.next();
-      if (ent.getKey().equals(Property.TABLE_FORMATTER_CLASS.toString())) {
-        Class<? extends Formatter> formatter;
-        try {
-          formatter = AccumuloClassLoader.loadClass(ent.getValue(), Formatter.class);
-        } catch (ClassNotFoundException e) {
-          return null;
-        }
-        
-        return formatter;
-      }
-    }
-    
-    return null;
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, Formatter.class,
Property.TABLE_FORMATTER_CLASS);
   }
   
   @Override
   public Options getOptions() {
-    Options o = new Options();
-    OptionGroup actionGroup = new OptionGroup();
+    Options options = super.getOptions();
     
-    formatterClassOption = new Option("f", "formatter", true, "fully qualified name of the
formatter class to use");
-    formatterClassOption.setArgName("className");
+    interpeterOption = new Option("i", "interpeter", false, "configure class as interpreter
also");
     
-    // Action to take: apply (default), remove, list
-    removeFormatterOption = new Option("r", "remove", false, "remove the current formatter");
-    listClassOption = new Option("l", "list", false, "display the current formatter");
+    options.addOption(interpeterOption);
     
-    actionGroup.addOption(formatterClassOption);
-    actionGroup.addOption(removeFormatterOption);
-    actionGroup.addOption(listClassOption);
-    actionGroup.setRequired(true);
-    
-    o.addOptionGroup(actionGroup);
-    o.addOption(OptUtil.tableOpt("table to set the formatter on"));
-    
-    return o;
+    return options;
   }
   
-  @Override
-  public int numArgs() {
-    return 0;
+  protected void setPlugin(CommandLine cl, Shell shellState, String tableName, String className)
throws AccumuloException, AccumuloSecurityException {
+    super.setPlugin(cl, shellState, tableName, className);
+    if (cl.hasOption(interpeterOption.getOpt()))
+      shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString(),
className);
   }
   
+  protected void removePlugin(CommandLine cl, Shell shellState, String tableName) throws
AccumuloException, AccumuloSecurityException {
+    super.removePlugin(cl, shellState, tableName);
+    if (cl.hasOption(interpeterOption.getOpt()))
+      shellState.getConnector().tableOperations().removeProperty(tableName, Property.TABLE_INTERPRETER_CLASS.toString());
+  }
 }

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
Wed Aug 22 19:55:43 2012
@@ -19,13 +19,12 @@ package org.apache.accumulo.core.util.sh
 import java.io.IOException;
 import java.util.Collections;
 
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.BatchScanner;
 import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.iterators.user.GrepIterator;
 import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
 import org.apache.accumulo.core.util.shell.Shell;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.MissingArgumentException;
@@ -36,14 +35,16 @@ public class GrepCommand extends ScanCom
   
   private Option numThreadsOpt;
   
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException,
AccumuloSecurityException, TableNotFoundException,
-      IOException, MissingArgumentException {
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
     
     String tableName = OptUtil.getTableOpt(cl, shellState);
     
     if (cl.getArgList().isEmpty())
       throw new MissingArgumentException("No terms specified");
     
+    Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
     // handle first argument, if present, the authorizations list to
     // scan with
     int numThreads = 20;
@@ -52,17 +53,17 @@ public class GrepCommand extends ScanCom
     }
     Authorizations auths = getAuths(cl, shellState);
     BatchScanner scanner = shellState.getConnector().createBatchScanner(tableName, auths,
numThreads);
-    scanner.setRanges(Collections.singletonList(getRange(cl)));
+    scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
     
     for (int i = 0; i < cl.getArgs().length; i++)
       setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i, cl.getArgs()[i],
scanner);
     
     try {
       // handle columns
-      fetchColumns(cl, scanner);
+      fetchColumns(cl, scanner, interpeter);
       
       // output the records
-      printRecords(cl, shellState, scanner);
+      printRecords(cl, shellState, scanner, formatter);
     } finally {
       scanner.close();
     }

Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java?rev=1376213&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
(added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+
+/**
+ * 
+ */
+public class InterpreterCommand extends ShellPluginConfigurationCommand {
+  
+  /**
+   * @param typeName
+   * @param tableProp
+   * @param classOpt
+   */
+  public InterpreterCommand() {
+    super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
+  }
+
+  @Override
+  public String description() {
+    return "specifies a scan interpreter to interpret scan range and column arguments";
+  }
+  
+  public static Class<? extends ScanInterpreter> getCurrentInterpreter(String tableName,
Shell shellState) {
+    return ShellPluginConfigurationCommand.getPluginClass(tableName, shellState, ScanInterpreter.class,
Property.TABLE_INTERPRETER_CLASS);
+  }
+}

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,24 +16,21 @@
  */
 package org.apache.accumulo.core.util.shell.commands;
 
-import java.io.IOException;
-
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.data.Range;
 import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
 import org.apache.accumulo.core.util.shell.Shell;
 import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.ParseException;
 import org.apache.hadoop.io.Text;
 
 public class MaxRowCommand extends ScanCommand {
   
-  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException,
AccumuloSecurityException, TableNotFoundException,
-      IOException, ParseException {
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
     String tableName = OptUtil.getTableOpt(cl, shellState);
-    Range range = getRange(cl);
+    
+    ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+    
+    Range range = getRange(cl, interpeter);
     Authorizations auths = getAuths(cl, shellState);
     Text startRow = range.getStartKey() == null ? null : range.getStartKey().getRow();
     Text endRow = range.getEndKey() == null ? null : range.getEndKey().getRow();

Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
(original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
Wed Aug 22 19:55:43 2012
@@ -32,6 +32,8 @@ import org.apache.accumulo.core.data.Val
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.format.BinaryFormatter;
 import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
 import org.apache.accumulo.core.util.shell.Shell;
 import org.apache.accumulo.core.util.shell.Shell.Command;
 import org.apache.accumulo.start.classloader.AccumuloClassLoader;
@@ -42,7 +44,7 @@ import org.apache.hadoop.io.Text;
 
 public class ScanCommand extends Command {
   
-  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt,
formatterOpt;
+  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt,
formatterOpt, interpreterOpt, formatterInterpeterOpt;
   protected Option timestampOpt;
   private Option optStartRowExclusive;
   private Option optEndRowExclusive;
@@ -50,12 +52,8 @@ public class ScanCommand extends Command
   public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
     String tableName = OptUtil.getTableOpt(cl, shellState);
     
-    Class<? extends Formatter> formatter = null;
-    
-    // Use the configured formatter unless one was provided
-    if (!cl.hasOption(formatterOpt.getOpt())) {
-      formatter = FormatterCommand.getCurrentFormatter(tableName, shellState);
-    }
+    Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
+    ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
     
     // handle first argument, if present, the authorizations list to
     // scan with
@@ -66,10 +64,10 @@ public class ScanCommand extends Command
     addScanIterators(shellState, scanner, tableName);
     
     // handle remaining optional arguments
-    scanner.setRange(getRange(cl));
+    scanner.setRange(getRange(cl, interpeter));
     
     // handle columns
-    fetchColumns(cl, scanner);
+    fetchColumns(cl, scanner, interpeter);
     
     // output the records
     if (cl.hasOption(showFewOpt.getOpt())) {
@@ -88,11 +86,7 @@ public class ScanCommand extends Command
       }
       
     } else {
-      if (null == formatter) {
-        printRecords(cl, shellState, scanner);
-      } else {
         printRecords(cl, shellState, scanner, formatter);
-      }
     }
     
     return 0;
@@ -116,21 +110,6 @@ public class ScanCommand extends Command
     }
   }
   
-  protected void printRecords(CommandLine cl, Shell shellState, Iterable<Entry<Key,Value>>
scanner) throws IOException {
-    if (cl.hasOption(formatterOpt.getOpt())) {
-      try {
-        String className = cl.getOptionValue(formatterOpt.getOpt());
-        Class<? extends Formatter> formatterClass = AccumuloClassLoader.loadClass(className,
Formatter.class);
-        
-        printRecords(cl, shellState, scanner, formatterClass);
-      } catch (ClassNotFoundException e) {
-        shellState.getReader().printString("Formatter class could not be loaded.\n" + e.getMessage()
+ "\n");
-      }
-    } else {
-      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
-    }
-  }
-  
   protected void printRecords(CommandLine cl, Shell shellState, Iterable<Entry<Key,Value>>
scanner, Class<? extends Formatter> formatter) throws IOException {
     shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()),
formatter);
   }
@@ -139,19 +118,58 @@ public class ScanCommand extends Command
     shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
   }
   
-  protected void fetchColumns(CommandLine cl, ScannerBase scanner) throws UnsupportedEncodingException
{
+  protected ScanInterpreter getInterpreter(CommandLine cl, String tableName, Shell shellState)
throws Exception {
+    
+    Class<? extends ScanInterpreter> clazz = null;
+    try {
+      if (cl.hasOption(interpreterOpt.getOpt())) {
+        clazz = AccumuloClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()),
ScanInterpreter.class);
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        clazz = AccumuloClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()),
ScanInterpreter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().printString("Interpreter class could not be loaded.\n" + e.getMessage()
+ "\n");
+    }
+
+    if (clazz == null)
+      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
+
+    if (clazz == null)
+      clazz = DefaultScanInterpreter.class;
+    
+    return clazz.newInstance();
+  }
+
+  protected Class<? extends Formatter> getFormatter(CommandLine cl, String tableName,
Shell shellState) throws IOException {
+    
+    try {
+      if (cl.hasOption(formatterOpt.getOpt())) {
+        return AccumuloClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()), Formatter.class);
+        
+      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+        return AccumuloClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()),
Formatter.class);
+      }
+    } catch (ClassNotFoundException e) {
+      shellState.getReader().printString("Formatter class could not be loaded.\n" + e.getMessage()
+ "\n");
+    }
+    
+    return shellState.getFormatter(tableName);
+  }
+  
+  protected void fetchColumns(CommandLine cl, ScannerBase scanner, ScanInterpreter formatter)
throws UnsupportedEncodingException {
     if (cl.hasOption(scanOptColumns.getOpt())) {
       for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
         String sa[] = a.split(":", 2);
         if (sa.length == 1)
-          scanner.fetchColumnFamily(new Text(a.getBytes(Shell.CHARSET)));
+          scanner.fetchColumnFamily(formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
         else
-          scanner.fetchColumn(new Text(sa[0].getBytes(Shell.CHARSET)), new Text(sa[1].getBytes(Shell.CHARSET)));
+          scanner.fetchColumn(formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
+              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
       }
     }
   }
   
-  protected Range getRange(CommandLine cl) throws UnsupportedEncodingException {
+  protected Range getRange(CommandLine cl, ScanInterpreter formatter) throws UnsupportedEncodingException
{
     if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) &&
cl.hasOption(scanOptRow.getOpt())) {
       // did not see a way to make commons cli do this check... it has mutually exclusive
options but does not support the or
       throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" +
OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
@@ -159,10 +177,14 @@ public class ScanCommand extends Command
     }
     
     if (cl.hasOption(scanOptRow.getOpt())) {
-      return new Range(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET)));
+      return new Range(formatter.interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
     } else {
       Text startRow = OptUtil.getStartRow(cl);
+      if (startRow != null)
+        startRow = formatter.interpretBeginRow(startRow);
       Text endRow = OptUtil.getEndRow(cl);
+      if (endRow != null)
+        endRow = formatter.interpretEndRow(endRow);
       boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
       boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
       return new Range(startRow, startInclusive, endRow, endInclusive);
@@ -198,6 +220,8 @@ public class ScanCommand extends Command
     disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of
output");
     showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
     formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter
class to use");
+    interpreterOpt = new Option("i", "interpreter", true, "fully qualified name of the interpreter
class to use");
+    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully qualified name
of a class that is a formatter and interpreter");
     
     scanOptAuths.setArgName("comma-separated-authorizations");
     scanOptRow.setArgName("row");
@@ -218,6 +242,8 @@ public class ScanCommand extends Command
     o.addOption(OptUtil.tableOpt("table to be scanned"));
     o.addOption(showFewOpt);
     o.addOption(formatterOpt);
+    o.addOption(interpreterOpt);
+    o.addOption(formatterInterpeterOpt);
     
     return o;
   }

Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java?rev=1376213&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
(added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.AccumuloClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.log4j.Logger;
+
+public abstract class ShellPluginConfigurationCommand extends Command {
+  private Option removePluginOption, pluginClassOption, listPluginOption;
+  
+  private String pluginType;
+  
+  private Property tableProp;
+  
+  private String classOpt;
+  
+  ShellPluginConfigurationCommand(String typeName, Property tableProp, String classOpt) {
+    this.pluginType = typeName;
+    this.tableProp = tableProp;
+    this.classOpt = classOpt;
+  }
+
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception
{
+    String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    if (cl.hasOption(removePluginOption.getOpt())) {
+      // Remove the property
+      removePlugin(cl, shellState, tableName);
+      
+      shellState.getReader().printString("Removed "+pluginType+" on " + tableName + "\n");
+    } else if (cl.hasOption(listPluginOption.getOpt())) {
+      // Get the options for this table
+      Iterator<Entry<String,String>> iter = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+      
+      while (iter.hasNext()) {
+        Entry<String,String> ent = iter.next();
+        
+        // List all parameters with the property name
+        if (ent.getKey().startsWith(tableProp.toString())) {
+          shellState.getReader().printString(ent.getKey() + ": " + ent.getValue() + "\n");
+        }
+      }
+    } else {
+      // Set the plugin with the provided options
+      String className = cl.getOptionValue(pluginClassOption.getOpt());
+      
+      // Set the plugin property on the table
+      setPlugin(cl, shellState, tableName, className);
+    }
+    
+    return 0;
+  }
+
+  protected void setPlugin(CommandLine cl, Shell shellState, String tableName, String className)
throws AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().setProperty(tableName, tableProp.toString(),
className);
+  }
+  
+  protected void removePlugin(CommandLine cl, Shell shellState, String tableName) throws
AccumuloException, AccumuloSecurityException {
+    shellState.getConnector().tableOperations().removeProperty(tableName, tableProp.toString());
+  }
+  
+  public static <T> Class<? extends T> getPluginClass(String tableName, Shell
shellState, Class<T> clazz, Property pluginProp) {
+    Iterator<Entry<String,String>> props;
+    try {
+      props = shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+    } catch (AccumuloException e) {
+      return null;
+    } catch (TableNotFoundException e) {
+      return null;
+    }
+    
+    while (props.hasNext()) {
+      Entry<String,String> ent = props.next();
+      if (ent.getKey().equals(pluginProp.toString())) {
+        Class<? extends T> pluginClazz;
+        try {
+          pluginClazz = AccumuloClassLoader.loadClass(ent.getValue(), clazz);
+        } catch (ClassNotFoundException e) {
+          Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class not found"
+ e.getMessage());
+          return null;
+        }
+        
+        return pluginClazz;
+      }
+    }
+    
+    return null;
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    OptionGroup actionGroup = new OptionGroup();
+    
+    pluginClassOption = new Option(classOpt, pluginType, true, "fully qualified name of the
" + pluginType + " class to use");
+    pluginClassOption.setArgName("className");
+    
+    // Action to take: apply (default), remove, list
+    removePluginOption = new Option("r", "remove", false, "remove the current "+pluginType+"");
+    listPluginOption = new Option("l", "list", false, "display the current "+pluginType+"");
+    
+    actionGroup.addOption(pluginClassOption);
+    actionGroup.addOption(removePluginOption);
+    actionGroup.addOption(listPluginOption);
+    actionGroup.setRequired(true);
+    
+    o.addOptionGroup(actionGroup);
+    o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+  
+}

Modified: accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
--- accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
(original)
+++ accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
Wed Aug 22 19:55:43 2012
@@ -211,7 +211,6 @@ public class FormatterCommandTest {
       this.iter = scanner.iterator();
       this.printTs = printTimestamps;
     }
-    
   }
   
 }



Mime
View raw message