justinmclean commented on code in PR #6483:
URL: https://github.com/apache/gravitino/pull/6483#discussion_r1962778305


##########
clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java:
##########
@@ -18,203 +18,581 @@
  */
 package org.apache.gravitino.cli.outputs;
 
-import java.util.ArrayList;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_LINE_COLUMN_SEPARATOR_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_LINE_LEFT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_LINE_RIGHT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_ROW_BORDER_COLUMN_SEPARATOR_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_ROW_BORDER_LEFT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_ROW_BORDER_MIDDLE_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.DATA_ROW_BORDER_RIGHT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.HEADER_BOTTOM_BORDER_COLUMN_SEPARATOR_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.HEADER_BOTTOM_BORDER_LEFT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.HEADER_BOTTOM_BORDER_MIDDLE_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.HEADER_BOTTOM_BORDER_RIGHT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_BOTTOM_BORDER_COLUMN_SEPARATOR_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_BOTTOM_BORDER_LEFT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_BOTTOM_BORDER_MIDDLE_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_BOTTOM_BORDER_RIGHT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_UPPER_BORDER_COLUMN_SEPARATOR_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_UPPER_BORDER_LEFT_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_UPPER_BORDER_MIDDLE_IDX;
+import static 
org.apache.gravitino.cli.outputs.OutputConstant.TABLE_UPPER_BORDER_RIGHT_IDX;
+
+import com.google.common.base.Preconditions;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
-import java.util.regex.Pattern;
+import java.util.Objects;
 import org.apache.gravitino.Catalog;
 import org.apache.gravitino.Metalake;
+import org.apache.gravitino.cli.CommandContext;
+
+/**
+ * Abstract base class for formatting entity information into ASCII-art 
tables. Provides
+ * comprehensive table rendering with features including: - Header and footer 
rows - Column
+ * alignments and padding - Border styles and row separators - Content 
overflow handling - Row
+ * numbers - Data limiting and sorting
+ */
+public abstract class TableFormat<T> extends BaseOutputFormat<T> {
+  public static final int PADDING = 1;
 
-/** Table format to print a pretty table to standard out. */
-public class TableFormat {
-  public static void output(Object object) {
-    if (object instanceof Metalake) {
-      new MetalakeTableFormat().output((Metalake) object);
-    } else if (object instanceof Metalake[]) {
-      new MetalakesTableFormat().output((Metalake[]) object);
-    } else if (object instanceof Catalog) {
-      new CatalogTableFormat().output((Catalog) object);
-    } else if (object instanceof Catalog[]) {
-      new CatalogsTableFormat().output((Catalog[]) object);
+  /**
+   * Routes the entity object to its appropriate table formatter. Creates a 
new formatter instance
+   * based on the object's type.
+   *
+   * @param entity The object to format.
+   * @param context the command context.
+   * @throws IllegalArgumentException if the object type is not supported
+   */
+  public static void output(Object entity, CommandContext context) {
+    if (entity instanceof Metalake) {
+      new MetalakeTableFormat(context).output((Metalake) entity);
+    } else if (entity instanceof Metalake[]) {
+      new MetalakeListTableFormat(context).output((Metalake[]) entity);
+    } else if (entity instanceof Catalog) {
+      new CatalogTableFormat(context).output((Catalog) entity);
+    } else if (entity instanceof Catalog[]) {
+      new CatalogListTableFormat(context).output((Catalog[]) entity);
     } else {
       throw new IllegalArgumentException("Unsupported object type");
     }
   }
 
-  static final class MetalakeTableFormat implements OutputFormat<Metalake> {
-    @Override
-    public void output(Metalake metalake) {
-      List<String> headers = Arrays.asList("metalake", "comment");
-      List<List<String>> rows = new ArrayList<>();
-      rows.add(Arrays.asList(metalake.name(), metalake.comment()));
-      TableFormatImpl tableFormat = new TableFormatImpl();
-      tableFormat.print(headers, rows);
+  /**
+   * Creates a new {@link TableFormat} with the specified properties.
+   *
+   * @param context the command context.
+   */
+  public TableFormat(CommandContext context) {
+    super(context);
+    // TODO: add other options for TableFormat
+  }
+
+  /**
+   * Get the formatted output string for the given columns.
+   *
+   * @param columns the columns to print.
+   * @return the table formatted output string.
+   */
+  public String getTableFormat(Column... columns) {
+    checkColumns(columns);
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+    String[] headers =
+        Arrays.stream(columns)
+            .map(Column::getHeader)
+            .filter(Objects::nonNull)
+            .toArray(String[]::new);
+
+    List<Character> borders = OutputConstant.BASIC_ASCII;
+    checkHeaders(headers, columns);
+
+    if (headers.length != columns.length) {
+      throw new IllegalArgumentException("Headers must be provided for all 
columns");
+    }
+
+    if (limit != -1) {
+      columns = getLimitedColumns(columns);
     }
+
+    try (OutputStreamWriter osw = new OutputStreamWriter(baos, 
StandardCharsets.UTF_8)) {
+      writeUpperBorder(osw, borders, System.lineSeparator(), columns);
+      writeHeader(osw, borders, System.lineSeparator(), columns);
+      writeHeaderBorder(osw, borders, System.lineSeparator(), columns);
+      writeData(osw, borders, columns, System.lineSeparator());
+      writeBottomBorder(osw, borders, System.lineSeparator(), columns);
+
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+
+    return new String(baos.toByteArray(), StandardCharsets.UTF_8);
   }
 
-  static final class MetalakesTableFormat implements OutputFormat<Metalake[]> {
-    @Override
-    public void output(Metalake[] metalakes) {
-      if (metalakes.length == 0) {
-        System.out.println("No metalakes exist.");
-      } else {
-        List<String> headers = Collections.singletonList("metalake");
-        List<List<String>> rows = new ArrayList<>();
-        for (int i = 0; i < metalakes.length; i++) {
-          rows.add(Arrays.asList(metalakes[i].name()));
-        }
-        TableFormatImpl tableFormat = new TableFormatImpl();
-        tableFormat.print(headers, rows);
-      }
+  private void checkColumns(Column... columns) {

Review Comment:
   I'm not sure that the Preconditions calls are adding anything. What does the 
user see if one of these calls fails?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@gravitino.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to