Index: src/contrib/hbase/src/test/org/apache/hadoop/hbase/shell/TestConsoleTable.java =================================================================== --- src/contrib/hbase/src/test/org/apache/hadoop/hbase/shell/TestConsoleTable.java (revision 0) +++ src/contrib/hbase/src/test/org/apache/hadoop/hbase/shell/TestConsoleTable.java (revision 0) @@ -0,0 +1,65 @@ +package org.apache.hadoop.hbase.shell; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +public class TestConsoleTable extends TestCase { + + private ByteArrayOutputStream baos; + private ConsoleTable console; + + protected void setUp() throws Exception { + baos = new ByteArrayOutputStream(); + System.setOut(new PrintStream(baos)); + console = new ConsoleTable(); + } + + /** + * Test the FreeMarker template ascii_header.ftl + */ + public void testASCIIHeader() throws Exception { + List headerList = new ArrayList(); + headerList.add("Table Name"); + + console.printHeader(headerList, true); + String header1 = "+------+----------------------+\n" + + "| No. | Table Name |\n" + + "+------+----------------------+\n"; + assertTrue(baos.toString("UTF-8").equals(header1)); + + baos.reset(); + console.printHeader(headerList, false); + String header2 = "+------+----------------------+\n"; + assertTrue(baos.toString("UTF-8").equals(header2)); + } + + /** + * Test the FreeMarker template ascii_line.ftl + */ + public void testASCIILine() throws Exception { + List lineList = new ArrayList(); + lineList.add("one_column"); + lineList.add("two_column"); + lineList.add("abcdefghijklmnopqrstuvwxyz"); + + console.printLine(0, lineList); + String line = "| 1 | one_column | two_column |" + + " abcdefghijklmnopq... |\n+------+----------------------+" + + "----------------------+----------------------+\n"; + assertTrue(baos.toString("UTF-8").equals(line)); + } + + /** + * Test the FreeMarker template ascii_footer.ftl + */ + public void testASCIIFooter() throws Exception { + console.printFooter(); + String footer = "\n"; + assertTrue(baos.toString("UTF-8").equals(footer)); + } + +} Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ConsoleTable.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ConsoleTable.java (revision 575028) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ConsoleTable.java (working copy) @@ -19,185 +19,89 @@ */ package org.apache.hadoop.hbase.shell; +import java.io.File; +import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.util.List; +import freemarker.template.Configuration; +import freemarker.template.SimpleHash; +import freemarker.template.Template; +import freemarker.template.TemplateException; + /** - * Manufactures console table, but stupid. + * Manufactures console table using FreeMarker templates. */ public class ConsoleTable { - private static PrintStream out; - static { + private final String ASCII_HEADER = "ascii_header.ftl"; + private final String ASCII_LINE = "ascii_line.ftl"; + private final String ASCII_FOOTER = "ascii_footer.ftl"; + + private Configuration cfg; + private PrintStream out; + + public ConsoleTable() { + cfg = new Configuration(); try { + cfg.setDirectoryForTemplateLoading( + new File ("templates")); + // Ultimately this is a poor location for the templates, should be moved. + } catch (IOException e) { + e.printStackTrace(); + } + try { out = new PrintStream(System.out, true, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } - public static void printHead(String name) { - out.println("+------+----------------------+"); - out.print("| No. | "); - out.printf("%-20s", name); - out.println(" |"); - } - - public static void printFoot() { - out.println("+------+----------------------+"); - out.println(); - } - - public static void printTable(int count, String name) { - out.println("+------+----------------------+"); - - if (name.length() > 20) { - int interval = 20; - - out.print("| "); - out.printf("%-4s", count + 1); - out.print(" | "); - out.printf("%-20s", name.substring(0, interval)); - out.println(" |"); - - for (int i = 0; i < name.length() / interval; i++) { - out.print("| "); - out.printf("%-4s", ""); - out.print(" | "); - - int end = ((interval * i) + interval + interval); - if (end > name.length()) { - out.printf("%-20s", name.substring(end - interval, - name.length())); - } else { - out.printf("%-20s", name.substring(end - interval, end)); - } - out.println(" |"); - } - - } else { - out.print("| "); - out.printf("%-4s", count + 1); - out.print(" | "); - out.printf("%-20s", name); - out.println(" |"); + public void printHeader(List fields, boolean showHeader) { + try { + Template temp = cfg.getTemplate(ASCII_HEADER); + + SimpleHash contents = new SimpleHash(); + contents.put("values", fields); + contents.put("showHeader", showHeader); + + temp.process(contents, new PrintWriter(out)); + + } catch (IOException e) { + e.printStackTrace(); + } catch (TemplateException te) { + te.printStackTrace(); } } - - public static void selectHead() { - out.println("+------+----------------------+" + - "----------------------+----------------------+"); - out.print("| No. | "); - out.printf("%-20s", "Row"); - out.printf(" | "); - out.printf("%-20s", "Column"); - out.printf(" | "); - out.printf("%-20s", "Cell"); - out.println(" | "); - } - - public static void printLine(int count, String key, String column, - String cellData) { - out.println("+------+----------------------+" + - "----------------------+----------------------+"); - - if (key.length() > 20 || column.length() > 20 || cellData.length() > 20) { - int interval = 20; - out.print("| "); - out.printf("%-4s", count + 1); - out.print(" | "); - if (key.length() > 20) - out.printf("%-20s", key.substring(0, interval)); - else - out.printf("%-20s", key); - out.print(" | "); - if (column.length() > 20) - out.printf("%-20s", column.substring(0, interval)); - else - out.printf("%-20s", column); - out.print(" | "); - if (cellData.length() > 20) - out.printf("%-20s", cellData.substring(0, interval)); - else - out.printf("%-20s", cellData); - out.println(" |"); - - // out.println(getBiggerInt(new int[]{ 3, 1, 9})); - int biggerStrLength = getBiggerInt(new int[] { key.length(), - column.length(), cellData.length() }); - - for (int i = 0; i < (biggerStrLength / interval); i++) { - out.print("| "); - out.printf("%-4s", ""); - out.print(" | "); - - int end = ((interval * i) + interval + interval); - - if (end > key.length()) { - if (key.length() > interval && end - interval < key.length()) { - out.printf("%-20s", key.substring(end - interval, - key.length())); - } else { - out.printf("%-20s", ""); - } - } else { - out.printf("%-20s", key.substring(end - interval, end)); - } - - out.print(" | "); - - if (end > column.length()) { - if (column.length() > interval && end - interval < column.length()) { - out.printf("%-20s", column.substring(end - interval, - column.length())); - } else { - out.printf("%-20s", ""); - } - } else { - out.printf("%-20s", column.substring(end - interval, end)); - } - - out.print(" | "); - if (end > cellData.length()) { - if (cellData.length() > interval && - end - interval < cellData.length()) { - out.printf("%-20s", - cellData.substring(end - interval, cellData.length())); - } else { - out.printf("%-20s", ""); - } - } else { - out.printf("%-20s", cellData.substring(end - interval, end)); - } - out.println(" |"); - } - - } else { - out.print("| "); - out.printf("%-4s", count + 1); - out.print(" | "); - out.printf("%-20s", key); - out.print(" | "); - out.printf("%-20s", column); - out.print(" | "); - out.printf("%-20s", cellData); - out.println(" |"); + + public void printLine(int index, List fields) { + try { + Template temp = cfg.getTemplate(ASCII_LINE); + + SimpleHash contents = new SimpleHash(); + contents.put("values", fields); + contents.put("index", new Integer(index)); + + temp.process(contents, new PrintWriter(out)); + + } catch (IOException e) { + e.printStackTrace(); + } catch (TemplateException te) { + te.printStackTrace(); } } - - public static int getBiggerInt(int[] integers) { - int result = -1; - for (int i = 0; i < integers.length; i++) { - if (integers[i] > result) { - result = integers[i]; - } + + public void printFooter() { + try { + Template temp = cfg.getTemplate(ASCII_FOOTER); + temp.process(new SimpleHash(), new PrintWriter(out)); + + } catch (IOException e) { + e.printStackTrace(); + } catch (TemplateException te) { + te.printStackTrace(); } - return result; } - - public static void selectFoot() { - out.println("+------+----------------------+" + - "----------------------+----------------------+"); - out.println(); - } } Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DescCommand.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DescCommand.java (revision 575028) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/DescCommand.java (working copy) @@ -20,6 +20,8 @@ package org.apache.hadoop.hbase.shell; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HConnection; @@ -51,12 +53,18 @@ } } - ConsoleTable.printHead("ColumnFamily Name"); + ConsoleTable console = new ConsoleTable(); + List headers = new ArrayList(1); + headers.add("ColumnFamily Name"); + console.printHeader(headers, true); + + List values; for (int ii = 0; ii < columns.length; ii++) { - String familyName = columns[ii].toString().replace(FAMILY_INDICATOR, ""); - ConsoleTable.printTable(ii, familyName); + values = new ArrayList(); + values.add(columns[ii].toString().replace(FAMILY_INDICATOR, "")); + console.printLine(ii, values); } - ConsoleTable.printFoot(); + console.printFooter(); return new ReturnMsg(1, columns.length + " columnfamilie(s) found."); } catch (IOException e) { Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/SelectCommand.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/SelectCommand.java (revision 575028) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/SelectCommand.java (working copy) @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.shell; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -49,6 +50,13 @@ HTable table = new HTable(conf, this.table); HBaseAdmin admin = new HBaseAdmin(conf); + // Setup for the console and the standard, 3-wide header + ConsoleTable console = new ConsoleTable(); + List values, header = new ArrayList(); + header.add("Row"); + header.add("Column"); + header.add("Cell"); + switch (getCondition()) { case 0: @@ -70,7 +78,7 @@ HStoreKey key = new HStoreKey(); TreeMap results = new TreeMap(); - ConsoleTable.selectHead(); + console.printHeader(header, true); int count = 0; while (scan.next(key, results)) { Text rowKey = key.getRow(); @@ -87,21 +95,25 @@ cellData = "ID : " + String.valueOf(info.getRegionId()); } - ConsoleTable.printLine(count, rowKey.toString(), columnKey.toString(), - cellData); + values = new ArrayList(); + values.add(rowKey.toString()); + values.add(columnKey.toString()); + values.add(cellData); + console.printLine(count, values); count++; } results = new TreeMap(); } - ConsoleTable.selectFoot(); + console.printFooter(); scan.close(); break; case 1: + console.printHeader(header, true); count = 0; - ConsoleTable.selectHead(); + for (Map.Entry entry : table.getRow(new Text(getRow())).entrySet()) { byte[] value = entry.getValue(); @@ -115,11 +127,14 @@ cellData = "ID : " + String.valueOf(info.getRegionId()); } - ConsoleTable.printLine(count, getRow().toString(), entry.getKey().toString(), - cellData); + values = new ArrayList(); + values.add(getRow().toString()); + values.add(entry.getKey().toString()); + values.add(cellData); + console.printLine(count, values); count++; } - ConsoleTable.selectFoot(); + console.printFooter(); break; @@ -131,7 +146,7 @@ HStoreKey k = new HStoreKey(); TreeMap r = new TreeMap(); - ConsoleTable.selectHead(); + console.printHeader(header, true); count = 0; while (scanner.next(k, r)) { Text rowKey = k.getRow(); @@ -139,13 +154,17 @@ for (Text columnKey : r.keySet()) { byte[] value = r.get(columnKey); String cellData = new String(value, HConstants.UTF8_ENCODING); - ConsoleTable.printLine(count, rowKey.toString(), columnKey.toString(), - cellData); + + values = new ArrayList(); + values.add(rowKey.toString()); + values.add(columnKey.toString()); + values.add(cellData); + console.printLine(count, values); count++; } results = new TreeMap(); } - ConsoleTable.selectFoot(); + console.printFooter(); scanner.close(); break; @@ -154,10 +173,15 @@ byte[] rs1 = table.get(new Text(getRow()), new Text(getColumn())); - ConsoleTable.selectHead(); - ConsoleTable.printLine(0, getRow(), getColumn(), - new String(rs1, HConstants.UTF8_ENCODING)); - ConsoleTable.selectFoot(); + console.printHeader(header, true); + + values = new ArrayList(); + values.add(getRow()); + values.add(getColumn()); + values.add(new String(rs1, HConstants.UTF8_ENCODING)); + console.printLine(0, values); + + console.printFooter(); break; @@ -165,12 +189,15 @@ byte[][] rs2 = table.get(new Text(getRow()), new Text(getColumn()), this.limit); - ConsoleTable.selectHead(); + console.printHeader(header, true); for (int i = 0; i < rs2.length; i++) { - ConsoleTable.printLine(i, getRow(), getColumn(), - new String(rs2[i], HConstants.UTF8_ENCODING)); + values = new ArrayList(); + values.add(getRow()); + values.add(getColumn()); + values.add(new String(rs2[i], HConstants.UTF8_ENCODING)); + console.printLine(0, values); } - ConsoleTable.selectFoot(); + console.printFooter(); break; @@ -178,11 +205,15 @@ byte[][] rs3 = table.get(new Text(getRow()), new Text(getColumn()), getTime(), this.limit); - ConsoleTable.selectHead(); + console.printHeader(header, true); for (int i = 0; i < rs3.length; i++) { - ConsoleTable.printLine(i, getRow(), getColumn(), new String(rs3[i], HConstants.UTF8_ENCODING)); + values = new ArrayList(); + values.add(getRow()); + values.add(getColumn()); + values.add(new String(rs3[i], HConstants.UTF8_ENCODING)); + console.printLine(0, values); } - ConsoleTable.selectFoot(); + console.printFooter(); break; Index: src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ShowCommand.java =================================================================== --- src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ShowCommand.java (revision 575028) +++ src/contrib/hbase/src/java/org/apache/hadoop/hbase/shell/ShowCommand.java (working copy) @@ -20,11 +20,18 @@ package org.apache.hadoop.hbase.shell; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseAdmin; import org.apache.hadoop.hbase.HTableDescriptor; +import freemarker.template.SimpleHash; +import freemarker.template.SimpleSequence; + public class ShowCommand extends BasicCommand { private String command; @@ -44,12 +51,19 @@ return new ReturnMsg(0, "Table not found."); } - ConsoleTable.printHead("Table Name"); - for (int i = 0; i < tableLength; i++) { - String tableName = tables[i].getName().toString(); - ConsoleTable.printTable(i, tableName); + ConsoleTable console = new ConsoleTable(); + List headers = new ArrayList(1); + headers.add("Table Name"); + console.printHeader(headers, true); + + List values; + for (int i= 0; i < tableLength; i++) { + values = new ArrayList(); + values.add(tables[i].getName().toString()); + console.printLine(i, values); } - ConsoleTable.printFoot(); + + console.printFooter(); return new ReturnMsg(1, tableLength + " table(s) found."); } Index: src/contrib/hbase/templates/ascii_defaults.ftl =================================================================== --- src/contrib/hbase/templates/ascii_defaults.ftl (revision 0) +++ src/contrib/hbase/templates/ascii_defaults.ftl (revision 0) @@ -0,0 +1,2 @@ +<#assign numColWidth=4> +<#assign textColWidth=20> \ No newline at end of file Index: src/contrib/hbase/templates/ascii_line.ftl =================================================================== --- src/contrib/hbase/templates/ascii_line.ftl (revision 0) +++ src/contrib/hbase/templates/ascii_line.ftl (revision 0) @@ -0,0 +1,9 @@ +<#include "ascii_defaults.ftl"> +<#t> +| ${ (index+1)?string?right_pad(numColWidth)} |<#rt> +<#list values as val> +<#if (val?length > textColWidth)> + ${ val?substring(0,textColWidth-3)}... <#rt> +<#else> + ${ val?right_pad(textColWidth)} | ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ Index: src/contrib/hbase/templates/ascii_header.ftl =================================================================== --- src/contrib/hbase/templates/ascii_header.ftl (revision 0) +++ src/contrib/hbase/templates/ascii_header.ftl (revision 0) @@ -0,0 +1,12 @@ +<#include "ascii_defaults.ftl"> +<#t> ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ +<#if showHeader> +| ${ "No."?right_pad(numColWidth)} |<#rt> +<#list values as val> +<#if (val?length > textColWidth)> + ${ val?substring(0,textColWidth-3)}... <#rt> +<#else> + ${ val?right_pad(textColWidth)} | ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ + Index: src/contrib/hbase/templates/ascii_footer.ftl =================================================================== --- src/contrib/hbase/templates/ascii_footer.ftl (revision 0) +++ src/contrib/hbase/templates/ascii_footer.ftl (revision 0) @@ -0,0 +1,3 @@ +<#include "ascii_defaults.ftl"> +<#nt> +<#nt> \ No newline at end of file Index: templates/ascii_defaults.ftl =================================================================== --- templates/ascii_defaults.ftl (revision 0) +++ templates/ascii_defaults.ftl (revision 0) @@ -0,0 +1,2 @@ +<#assign numColWidth=4> +<#assign textColWidth=20> \ No newline at end of file Index: templates/ascii_line.ftl =================================================================== --- templates/ascii_line.ftl (revision 0) +++ templates/ascii_line.ftl (revision 0) @@ -0,0 +1,9 @@ +<#include "ascii_defaults.ftl"> +<#t> +| ${ (index+1)?string?right_pad(numColWidth)} |<#rt> +<#list values as val> +<#if (val?length > textColWidth)> + ${ val?substring(0,textColWidth-3)}... <#rt> +<#else> + ${ val?right_pad(textColWidth)} | ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ Index: templates/ascii_header.ftl =================================================================== --- templates/ascii_header.ftl (revision 0) +++ templates/ascii_header.ftl (revision 0) @@ -0,0 +1,12 @@ +<#include "ascii_defaults.ftl"> +<#t> ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ +<#if showHeader> +| ${ "No."?right_pad(numColWidth)} |<#rt> +<#list values as val> +<#if (val?length > textColWidth)> + ${ val?substring(0,textColWidth-3)}... <#rt> +<#else> + ${ val?right_pad(textColWidth)} | ++-${ ""?right_pad(numColWidth,"-")}-+<#list values as spacer>-${ ""?right_pad(textColWidth,"-")}-+ + Index: templates/ascii_footer.ftl =================================================================== --- templates/ascii_footer.ftl (revision 0) +++ templates/ascii_footer.ftl (revision 0) @@ -0,0 +1,3 @@ +<#include "ascii_defaults.ftl"> +<#nt> +<#nt> \ No newline at end of file