Paul Martin
2016-04-30 a502d96a860456ec5e8c96761db70f7cabb74751
src/main/java/com/gitblit/utils/FlipTable.java
@@ -19,7 +19,7 @@
/**
 * This is a forked version of FlipTables which supports controlling the
 * displayed borders.
 * displayed borders and gracefully handles null cell values.
 *
 * FULL = all borders
 * BODY_COLS = header + perimeter + column separators
@@ -36,15 +36,19 @@
 * </pre>
 */
public final class FlipTable {
   private static final String EMPTY = "(empty)";
   public static final String EMPTY = "(empty)";
   public static enum Borders {
      FULL(7), BODY_COLS(5), COLS(4), BODY(1), HEADER(0);
      FULL(15), BODY_HCOLS(13), HCOLS(12), BODY(9), HEADER(8), COLS(4);
      final int bitmask;
      private Borders(int bitmask) {
         this.bitmask = bitmask;
      }
      boolean header() {
         return isset(0x8);
      }
      boolean body() {
@@ -65,12 +69,12 @@
   }
   /** Create a new table with the specified headers and row data. */
   public static String of(String[] headers, String[][] data) {
   public static String of(String[] headers, Object[][] data) {
      return of(headers, data, Borders.FULL);
   }
   /** Create a new table with the specified headers and row data. */
   public static String of(String[] headers, String[][] data, Borders borders) {
   public static String of(String[] headers, Object[][] data, Borders borders) {
      if (headers == null)
         throw new NullPointerException("headers == null");
      if (headers.length == 0)
@@ -81,13 +85,13 @@
   }
   private final String[] headers;
   private final String[][] data;
   private final Object[][] data;
   private final Borders borders;
   private final int columns;
   private final int[] columnWidths;
   private final int emptyWidth;
   private FlipTable(String[] headers, String[][] data, Borders borders) {
   private FlipTable(String[] headers, Object[][] data, Borders borders) {
      this.headers = headers;
      this.data = data;
      this.borders = borders;
@@ -95,13 +99,17 @@
      columns = headers.length;
      columnWidths = new int[columns];
      for (int row = -1; row < data.length; row++) {
         String[] rowData = (row == -1) ? headers : data[row];
         Object[] rowData = (row == -1) ? headers : data[row];
         if (rowData.length != columns) {
            throw new IllegalArgumentException(String.format("Row %s's %s columns != %s columns", row + 1,
                  rowData.length, columns));
         }
         for (int column = 0; column < columns; column++) {
            for (String rowDataLine : rowData[column].split("\\n")) {
            Object cell = rowData[column];
            if (cell == null) {
               continue;
            }
            for (String rowDataLine : cell.toString().split("\\n")) {
               columnWidths[column] = Math.max(columnWidths[column], rowDataLine.length());
            }
         }
@@ -123,20 +131,22 @@
   @Override
   public String toString() {
      StringBuilder builder = new StringBuilder();
      printDivider(builder, "╔═╤═╗");
      if (borders.header()) {
         printDivider(builder, "╔═╤═╗");
      }
      printData(builder, headers, true);
      if (data.length == 0) {
         if (borders.body()) {
            printDivider(builder, "╠═╧═╣");
            builder.append('║').append(pad(emptyWidth, EMPTY)).append("║\n");
            printDivider(builder, "╚═══╝");
         } else {
         } else if (borders.header()) {
            printDivider(builder, "╚═╧═╝");
            builder.append(' ').append(pad(emptyWidth, EMPTY)).append(" \n");
         }
      } else {
         for (int row = 0; row < data.length; row++) {
            if (row == 0) {
            if (row == 0 && borders.header()) {
               if (borders.body()) {
                  if (borders.columns()) {
                     printDivider(builder, "╠═╪═╣");
@@ -149,6 +159,12 @@
                  } else {
                     printDivider(builder, "╚═╧═╝");
                  }
               }
            } else if (row == 0 && !borders.header()) {
               if (borders.columns()) {
                  printDivider(builder, " ─┼─ ");
               } else {
                  printDivider(builder, " ─┼─ ");
               }
            } else if (borders.rows()) {
               if (borders.columns()) {
@@ -178,11 +194,11 @@
      out.append(format.charAt(4)).append('\n');
   }
   private void printData(StringBuilder out, String[] data, boolean isHeader) {
   private void printData(StringBuilder out, Object[] data, boolean isHeader) {
      for (int line = 0, lines = 1; line < lines; line++) {
         for (int column = 0; column < columns; column++) {
            if (column == 0) {
               if (isHeader || borders.body()) {
               if ((isHeader && borders.header()) || borders.body()) {
                  out.append('║');
               } else {
                  out.append(' ');
@@ -192,12 +208,16 @@
            } else {
               out.append(' ');
            }
            String[] cellLines = data[column].split("\\n");
            Object cell = data[column];
            if (cell == null) {
               cell = "";
            }
            String[] cellLines = cell.toString().split("\\n");
            lines = Math.max(lines, cellLines.length);
            String cellLine = line < cellLines.length ? cellLines[line] : "";
            out.append(pad(columnWidths[column], cellLine));
         }
         if (isHeader || borders.body()) {
         if ((isHeader && borders.header()) || borders.body()) {
            out.append("║\n");
         } else {
            out.append('\n');