changeset 1960:7e9e2f81b86c

Add sorting ability to TableRenderer For backport compatibility purposes, new functionality is added in SortedTableRenderer instead Reviewed-by: omajid, jkang, jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-July/014712.html Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019718.html PR3040
author Lukasz Dracz <ldracz@redhat.com>
date Tue, 21 Jul 2015 16:10:45 -0400
parents 3784a15aef43
children 2c970a73043a
files client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/AgentListFormatter.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java common/core/src/main/java/com/redhat/thermostat/common/cli/SortedTableRenderer.java common/core/src/main/java/com/redhat/thermostat/common/cli/TableRenderer.java common/core/src/test/java/com/redhat/thermostat/common/cli/SortedTableRendererTest.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileResultFormatter.java
diffstat 10 files changed, 350 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/AgentListFormatter.java	Thu May 12 11:17:00 2016 -0400
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/AgentListFormatter.java	Tue Jul 21 16:10:45 2015 -0400
@@ -40,7 +40,7 @@
 import java.text.DateFormat;
 import java.util.Date;
 
-import com.redhat.thermostat.common.cli.TableRenderer;
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.model.AgentInformation;
 
@@ -55,10 +55,10 @@
     private static final String START_TIME = translator.localize(LocaleResources.START_TIME).getContents();
     private static final String STOP_TIME = translator.localize(LocaleResources.STOP_TIME).getContents();
 
-    private final TableRenderer tableRenderer = new TableRenderer(NUM_COLUMNS);
+    private final SortedTableRenderer tableRenderer = new SortedTableRenderer(NUM_COLUMNS);
 
     void addHeader() {
-        printLine(AGENT_ID, CONFIG_LISTEN_ADDRESS, START_TIME, STOP_TIME);
+        tableRenderer.printHeader(AGENT_ID, CONFIG_LISTEN_ADDRESS, START_TIME, STOP_TIME);
     }
 
     void addAgent(AgentInformation info) {
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java	Thu May 12 11:17:00 2016 -0400
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMListFormatter.java	Tue Jul 21 16:10:45 2015 -0400
@@ -38,7 +38,7 @@
 
 import java.io.PrintStream;
 
-import com.redhat.thermostat.common.cli.TableRenderer;
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.model.AgentInformation;
@@ -60,14 +60,19 @@
     private static final String STATUS_EXITED = translator.localize(LocaleResources.VM_STATUS_EXITED).getContents();
     private static final String STATUS_UNKNOWN = translator.localize(LocaleResources.VM_STATUS_UNKNOWN).getContents();
 
-    private final TableRenderer tableRenderer = new TableRenderer(NUM_COLUMNS);
+    private final SortedTableRenderer tableRenderer = new SortedTableRenderer(NUM_COLUMNS);
+
+    VMListFormatter() {
+        tableRenderer.sortByColumn(0);
+        tableRenderer.sortByColumn(2);
+    }
 
     void addVM(VmRef vm, AgentInformation agentInfo, VmInfo info) {
         printVM(vm, agentInfo, info);
     }
 
     void addHeader() {
-        printLine(HOST_ID, HOST, VM_ID, VM_PID, VM_STATUS, VM_NAME);
+        tableRenderer.printHeader(HOST_ID, HOST, VM_ID, VM_PID, VM_STATUS, VM_NAME);
     }
 
     void format(PrintStream out) {
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java	Thu May 12 11:17:00 2016 -0400
+++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/VMStatPrinter.java	Tue Jul 21 16:10:45 2015 -0400
@@ -50,6 +50,7 @@
 
 import com.redhat.thermostat.client.cli.VMStatPrintDelegate;
 import com.redhat.thermostat.common.OrderedComparator;
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import com.redhat.thermostat.common.cli.TableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
@@ -67,7 +68,7 @@
     private List<VMStatPrintDelegate> delegates;
     private PrintStream out;
     private TimeStampedPojoCorrelator correlator;
-    private TableRenderer table;
+    private SortedTableRenderer table;
     private int numCols;
     private Map<VMStatPrintDelegate, DelegateInfo> delegateInfo;
 
@@ -148,7 +149,7 @@
     private void printStats(List<List<? extends TimeStampedPojo>> allStats, List<String> headers) {
         correlate(allStats);
         numCols = headers.size();
-        table = new TableRenderer(numCols);
+        table = new SortedTableRenderer(numCols);
         printHeaders(table, headers);
         printUpdatedStatsImpl();
     }
@@ -193,8 +194,8 @@
         table.printLine(line);
     }
 
-    private void printHeaders(TableRenderer table, List<String> headers) {
-        table.printLine(headers.toArray(new String[headers.size()]));
+    private void printHeaders(SortedTableRenderer table, List<String> headers) {
+        table.printHeader(headers.toArray(new String[headers.size()]));
     }
 
     private void correlate(List<List<? extends TimeStampedPojo>> allStats) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/SortedTableRenderer.java	Tue Jul 21 16:10:45 2015 -0400
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.common.cli;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class SortedTableRenderer extends TableRenderer {
+
+    private String[] header;
+    private List<Integer> columnSortingQueue = new ArrayList<>();
+
+    public SortedTableRenderer(int numColumns, int minWidth) {
+        super(numColumns, minWidth);
+    }
+
+    public SortedTableRenderer(int numColumns) {
+        super(numColumns);
+    }
+
+    @Override
+    public void printLine(String... line) {
+        checkLine(line);
+        super.printLine(line);
+    }
+
+    public void printHeader(String... line) {
+        checkLine(line);
+        this.header = line;
+    }
+
+    @Override
+    public void render(PrintStream out) {
+        if (lastPrintedLine == -1 && header != null) {
+            renderLine(out, header);
+        }
+        sortLines();
+        super.render(out);
+    }
+
+    private void sortLines() {
+        Collections.sort(lines, new Comparator<String[]>() {
+            @Override
+            public int compare(final String[] lines1, final String[] lines2) {
+                int comparison = 0;
+                for (Integer column : columnSortingQueue) {
+                    comparison = lines1[column].compareTo(lines2[column]);
+                    if (comparison != 0) {
+                        break;
+                    }
+                }
+                return comparison;
+            }
+        });
+    }
+
+    public void sortByColumn(int column) {
+        if (column < numColumns) {
+            columnSortingQueue.add(column);
+        } else {
+            throw new IllegalArgumentException("Invalid number of columns: " + column + ", expected: " + numColumns);
+        }
+    }
+}
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/TableRenderer.java	Thu May 12 11:17:00 2016 -0400
+++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/TableRenderer.java	Tue Jul 21 16:10:45 2015 -0400
@@ -43,12 +43,12 @@
 
 public class TableRenderer {
 
-    private List<String[]> lines;
-    private int[] maxColumnWidths;
-    private int lastPrintedLine = -1;
+    protected List<String[]> lines;
+    protected int[] maxColumnWidths;
+    protected int lastPrintedLine = -1;
 
-    private int numColumns;
-    private int minWidth;
+    protected int numColumns;
+    protected int minWidth;
 
     public TableRenderer(int numColumns) {
         this(numColumns, 1);
@@ -62,10 +62,14 @@
     }
 
     public void printLine(String... line) {
+        checkLine(line);
+        lines.add(line);
+    }
+
+    protected void checkLine(String... line) {
         if (line.length != numColumns) {
             throw new IllegalArgumentException("Invalid number of columns: " + line.length + ", expected: " + numColumns);
         }
-        lines.add(line);
         for (int i = 0; i < numColumns; i++) {
             maxColumnWidths[i] = Math.max(Math.max(maxColumnWidths[i], line[i].length()), minWidth);
         }
@@ -84,7 +88,7 @@
         }
     }
 
-    private void renderLine(PrintStream out, String[] line) {
+    protected void renderLine(PrintStream out, String[] line) {
         for (int i = 0; i < numColumns; i++) {
             out.print(line[i]);
             padOrNewline(out, line, i);
@@ -92,7 +96,7 @@
         }
     }
 
-    private void padOrNewline(PrintStream out, String[] line, int i) {
+    protected void padOrNewline(PrintStream out, String[] line, int i) {
         if (i < numColumns - 1) {
             int pad = maxColumnWidths[i] - line[i].length() + 1;
             fillSpaces(out, pad);
@@ -101,7 +105,7 @@
         }
     }
 
-    private void fillSpaces(PrintStream out, int pad) {
+    protected void fillSpaces(PrintStream out, int pad) {
         for (int i = 0; i < pad; i++) {
             out.print(" ");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/common/cli/SortedTableRendererTest.java	Tue Jul 21 16:10:45 2015 -0400
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.common.cli;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+
+import static org.junit.Assert.assertEquals;
+
+public class SortedTableRendererTest {
+
+    private SortedTableRenderer tableRenderer;
+    private ByteArrayOutputStream out;
+
+    @Before
+    public void setUp() {
+        tableRenderer = new SortedTableRenderer(3);
+        out = new ByteArrayOutputStream();
+    }
+
+    @After
+    public void tearDown() {
+        out = null;
+        tableRenderer = null;
+    }
+
+    @Test
+    public void testSingleLine() {
+        tableRenderer.printLine("hello", "fluff", "world");
+        tableRenderer.render(out);
+        assertEquals("hello fluff world\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testMultiLine() {
+        tableRenderer.printLine("hello", "fluff", "world");
+        tableRenderer.printLine("looooooong", "f1", "foobar");
+        tableRenderer.printLine("f2", "shoooooooooooort", "poo");
+        tableRenderer.render(out);
+        assertEquals("hello      fluff            world\n" +
+                "looooooong f1               foobar\n" +
+                "f2         shoooooooooooort poo\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testMultiLineContinuous() {
+        tableRenderer.printHeader("TITLE", "TIME", "PLACE");
+        tableRenderer.printLine("hello", "fluff", "world");
+        tableRenderer.printLine("looooooong", "f1", "foobar");
+        tableRenderer.printLine("f2", "shoooooooooooort", "poo");
+        tableRenderer.render(out);
+        assertEquals("TITLE      TIME             PLACE\n" +
+                "hello      fluff            world\n" +
+                "looooooong f1               foobar\n" +
+                "f2         shoooooooooooort poo\n", new String(out.toByteArray()));
+        tableRenderer.printLine("f3", "foobar", "poo");
+        tableRenderer.render(out);
+        assertEquals("TITLE      TIME             PLACE\n" +
+                "hello      fluff            world\n" +
+                "looooooong f1               foobar\n" +
+                "f2         shoooooooooooort poo\n" +
+                "f3         foobar           poo\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testMultiLineSorting() {
+        tableRenderer.sortByColumn(0);
+        tableRenderer.sortByColumn(2);
+        tableRenderer.sortByColumn(1);
+        tableRenderer.printLine("animal", "brown", "bear");
+        tableRenderer.printLine("animal", "black", "bear");
+        tableRenderer.printLine("animal", "grey", "rhino");
+        tableRenderer.printLine("animal", "aqua-green", "turtle");
+        tableRenderer.printLine("animal", "polar", "bear");
+        tableRenderer.printLine("animal", "green", "alligator");
+        tableRenderer.printLine("animal", "white", "rabbit");
+        tableRenderer.printLine("animal", "brown", "alligator");
+        tableRenderer.printLine("animal", "brown", "rabbit");
+        tableRenderer.printLine("animal", "brown", "rat");
+        tableRenderer.printLine("bird", "red", "parrot");
+        tableRenderer.printLine("bird", "green", "parrot");
+        tableRenderer.printLine("bird", "blue", "parrot");
+        tableRenderer.printLine("bird", "red", "ostrich");
+        tableRenderer.printLine("bird", "yellow", "rooster");
+        tableRenderer.printLine("bird", "tuxedo", "penguin");
+        tableRenderer.printLine("fish", "yellow", "trout");
+        tableRenderer.printLine("fish", "rainbow", "trout");
+        tableRenderer.printLine("fish", "golden", "trout");
+        tableRenderer.printLine("fish", "tiger", "trout");
+
+        tableRenderer.render(out);
+        assertEquals("animal brown      alligator\n" +
+                "animal green      alligator\n" +
+                "animal black      bear\n" +
+                "animal brown      bear\n" +
+                "animal polar      bear\n" +
+                "animal brown      rabbit\n" +
+                "animal white      rabbit\n" +
+                "animal brown      rat\n" +
+                "animal grey       rhino\n" +
+                "animal aqua-green turtle\n" +
+                "bird   red        ostrich\n" +
+                "bird   blue       parrot\n" +
+                "bird   green      parrot\n" +
+                "bird   red        parrot\n" +
+                "bird   tuxedo     penguin\n" +
+                "bird   yellow     rooster\n" +
+                "fish   golden     trout\n" +
+                "fish   rainbow    trout\n" +
+                "fish   tiger      trout\n" +
+                "fish   yellow     trout\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testHeader() {
+        tableRenderer.printHeader("HEADER", "TITLE", "SUBTITLE");
+        tableRenderer.render(out);
+        assertEquals("HEADER TITLE SUBTITLE\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testHeaderWithLine() {
+        tableRenderer.printHeader("HEADER", "TITLE", "SUBTITLE");
+        tableRenderer.printLine("hello", "foo", "subtitle");
+        tableRenderer.render(out);
+        assertEquals("HEADER TITLE SUBTITLE\n" +
+                "hello  foo   subtitle\n", new String(out.toByteArray()));
+    }
+
+    @Test
+    public void testHeaderNotSet() {
+        tableRenderer.printLine("No", "Header", "Present");
+        tableRenderer.render(out);
+        assertEquals("No Header Present\n", new String(out.toByteArray()));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testMultiLineSortingWithColumnsOutOfRange() {
+        tableRenderer.sortByColumn(3);
+        tableRenderer.sortByColumn(7);
+        tableRenderer.sortByColumn(1);
+        tableRenderer.printLine("animal", "brown", "bear");
+        tableRenderer.printLine("animal", "black", "bear");
+        tableRenderer.printLine("animal", "grey", "rhino");
+        tableRenderer.printLine("animal", "aqua-green", "turtle");
+        tableRenderer.printLine("animal", "polar", "bear");
+        tableRenderer.printLine("animal", "green", "alligator");
+        tableRenderer.printLine("animal", "white", "rabbit");
+        tableRenderer.printLine("animal", "brown", "alligator");
+        tableRenderer.printLine("animal", "brown", "rabbit");
+        tableRenderer.printLine("animal", "brown", "rat");
+        tableRenderer.printLine("bird", "red", "parrot");
+        tableRenderer.printLine("bird", "green", "parrot");
+        tableRenderer.printLine("bird", "blue", "parrot");
+        tableRenderer.printLine("bird", "red", "ostrich");
+        tableRenderer.printLine("bird", "yellow", "rooster");
+        tableRenderer.printLine("bird", "tuxedo", "penguin");
+        tableRenderer.printLine("fish", "yellow", "trout");
+        tableRenderer.printLine("fish", "rainbow", "trout");
+        tableRenderer.printLine("fish", "golden", "trout");
+        tableRenderer.printLine("fish", "tiger", "trout");
+
+        tableRenderer.render(out);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testInvalidLine() {
+        tableRenderer.printLine("hello", "fluff", "world", "boom");
+    }
+
+}
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java	Thu May 12 11:17:00 2016 -0400
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/FindObjectsCommand.java	Tue Jul 21 16:10:45 2015 -0400
@@ -39,6 +39,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDump;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -47,7 +48,6 @@
 import com.redhat.thermostat.common.cli.AbstractCommand;
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.common.cli.TableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.vm.heap.analysis.command.locale.LocaleResources;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO;
@@ -97,8 +97,8 @@
         int limit = parseLimit(limitArg);
         Collection<String> results = heapDump.searchObjects(searchTerm, limit);
 
-        TableRenderer table = new TableRenderer(2);
-        table.printLine(HEADER_OBJECT_ID, HEADER_TYPE);
+        SortedTableRenderer table = new SortedTableRenderer(2);
+        table.printHeader(HEADER_OBJECT_ID, HEADER_TYPE);
         for (String objectId : results) {
             JavaHeapObject obj = heapDump.findObject(objectId);
             String id = obj.getIdString();
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java	Thu May 12 11:17:00 2016 -0400
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ListHeapDumpsCommand.java	Tue Jul 21 16:10:45 2015 -0400
@@ -40,6 +40,7 @@
 import java.util.Collection;
 import java.util.Date;
 
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
@@ -84,9 +85,9 @@
     public void run(CommandContext ctx) throws CommandException {
         HostVMArguments args = new HostVMArguments(ctx.getArguments(), false, false);
 
-        TableRenderer renderer = new TableRenderer(4);
+        SortedTableRenderer renderer = new SortedTableRenderer(4);
 
-        renderer.printLine(COLUMN_NAMES);
+        renderer.printHeader(COLUMN_NAMES);
 
         ServiceReference hostDAORef = context.getServiceReference(HostInfoDAO.class.getName());
         requireNonNull(hostDAORef, translator.localize(LocaleResources.HOST_SERVICE_UNAVAILABLE));
--- a/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java	Thu May 12 11:17:00 2016 -0400
+++ b/vm-heap-analysis/command/src/main/java/com/redhat/thermostat/vm/heap/analysis/command/internal/ShowHeapHistogramCommand.java	Tue Jul 21 16:10:45 2015 -0400
@@ -38,6 +38,7 @@
 
 import java.io.PrintStream;
 
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceReference;
@@ -46,7 +47,6 @@
 import com.redhat.thermostat.common.cli.Arguments;
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.common.cli.TableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.vm.heap.analysis.command.locale.LocaleResources;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO;
@@ -100,8 +100,8 @@
     }
 
     private void printHeapHistogram(ObjectHistogram histogram, PrintStream out) {
-        TableRenderer table = new TableRenderer(3);
-        table.printLine(translator.localize(LocaleResources.TABLE_CLASS_NAME).getContents(),
+        SortedTableRenderer table = new SortedTableRenderer(3);
+        table.printHeader(translator.localize(LocaleResources.TABLE_CLASS_NAME).getContents(),
                 translator.localize(LocaleResources.TABLE_NUMBER_INSTANCES).getContents(),
                 translator.localize(LocaleResources.TABLE_TOTAL_SIZE).getContents());
         for (HistogramRecord rec : histogram.getHistogram()) {
--- a/vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileResultFormatter.java	Thu May 12 11:17:00 2016 -0400
+++ b/vm-profiler/client-cli/src/main/java/com/redhat/thermostat/vm/profiler/client/cli/internal/ProfileResultFormatter.java	Tue Jul 21 16:10:45 2015 -0400
@@ -38,7 +38,7 @@
 
 import java.io.OutputStream;
 
-import com.redhat.thermostat.common.cli.TableRenderer;
+import com.redhat.thermostat.common.cli.SortedTableRenderer;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.vm.profiler.client.core.ProfilingResult.MethodInfo;
 
@@ -52,10 +52,10 @@
     private static final String HEADER_TIME = translator.localize(LocaleResources.METHOD_PROFILE_HEADER_TIME).getContents();
     private static final String HEADER_NAME = translator.localize(LocaleResources.METHOD_PROFILE_HEADER_NAME).getContents();
 
-    private TableRenderer renderer = new TableRenderer(NUM_COLUMNS);
+    private SortedTableRenderer renderer = new SortedTableRenderer(NUM_COLUMNS);
 
     public void addHeader() {
-        printLine(HEADER_PERCENTAGE, HEADER_TIME, HEADER_NAME);
+        renderer.printHeader(HEADER_PERCENTAGE, HEADER_TIME, HEADER_NAME);
     }
 
     public void addMethodInfo(MethodInfo methodInfo) {