You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2019/08/30 02:43:06 UTC
[knox] branch master updated: KNOX-2002 - Add a KnoxShellTable to
Represent and Render Output in Tabular Format
This is an automated email from the ASF dual-hosted git repository.
lmccay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 5d3acde KNOX-2002 - Add a KnoxShellTable to Represent and Render Output in Tabular Format
5d3acde is described below
commit 5d3acde92d6d82da15f32bf1289999b63f6d82dd
Author: lmccay <lm...@apache.org>
AuthorDate: Thu Aug 29 22:42:43 2019 -0400
KNOX-2002 - Add a KnoxShellTable to Represent and Render Output in Tabular Format
---
.../apache/knox/gateway/shell/KnoxShellTable.java | 151 +++++++++++++++++++++
.../knox/gateway/shell/KnoxShellTableTest.java | 108 +++++++++++++++
2 files changed, 259 insertions(+)
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellTable.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellTable.java
new file mode 100644
index 0000000..9905c42
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/KnoxShellTable.java
@@ -0,0 +1,151 @@
+/*
+ * 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.knox.gateway.shell;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+* Simple table representation and text based rendering of a table via toString().
+* Headers are optional but when used must have the same count as columns
+* within the rows.
+*/
+public class KnoxShellTable {
+ private static int CELL_PAD_SIZE = 2;
+ private static char CELL_CORNER_CHAR = '+';
+ private static char CELL_WALL_CHAR = '|';
+ private static char CELL_DASH_CHAR = '-';
+
+ private List<String> headers = new ArrayList<String>();
+ private List<List<String>> rows = new ArrayList<List<String>>();
+
+ public KnoxShellTable header(String header) {
+ headers.add(header);
+ return this;
+ }
+
+ public KnoxShellTable row() {
+ List<String> row = new ArrayList<String>();
+ rows.add(row);
+ return this;
+ }
+
+ public KnoxShellTable value(String value) {
+ int index = rows.size() - 1;
+ if (index == -1) {
+ index = 0;
+ }
+ List<String> row = rows.get(index);
+ row.add(value);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ if (!headers.isEmpty() && headers.size() != rows.get(0).size()) {
+ throw new IllegalStateException("Number of columns within rows and headers must be the same.");
+ }
+ StringBuilder sb = new StringBuilder();
+ Map<Integer, Integer> widthMap = getWidthMap();
+
+ int colCount = rows.get(0).size();
+ if (!headers.isEmpty()) {
+ createBorder(sb, colCount, widthMap);
+ newLine(sb, 1);
+
+ sb.append(CELL_WALL_CHAR);
+ for (int i = 0; i < colCount; i++) {
+ sb.append(centerString(widthMap.get(i) + 4, headers.get(i))).append(CELL_WALL_CHAR);
+ }
+ newLine(sb, 1);
+ }
+ createBorder(sb, colCount, widthMap);
+
+ for (List<String> row : rows) {
+ newLine(sb, 1);
+ sb.append(CELL_WALL_CHAR);
+ for (int i = 0; i < row.size(); i++) {
+ sb.append(centerString(widthMap.get(i) + 4, row.get(i))).append(CELL_WALL_CHAR);
+ }
+ }
+
+ newLine(sb, 1);
+ createBorder(sb, colCount, widthMap);
+ newLine(sb, 1);
+
+ return sb.toString();
+ }
+
+ private void newLine(StringBuilder sb, int count) {
+ for (int i = 0; i < count; i++) {
+ sb.append('\n');
+ }
+ }
+
+ private String centerString(int width, String s) {
+ s = ensureEvenLength(s);
+ return String.format(Locale.ROOT, "%-" + width + "s", String.format(Locale.ROOT, "%" + (s.length() + (width - s.length()) / 2) + "s", s));
+ }
+
+ private String ensureEvenLength(String s) {
+ if (s.length() % 2 != 0) {
+ s = s + " ";
+ }
+ return s;
+ }
+
+ private void createBorder(StringBuilder sb, int headerCount, Map<Integer, Integer> widthMap) {
+ for (int i = 0; i < headerCount; i++) {
+ if (i == 0) {
+ sb.append(CELL_CORNER_CHAR);
+ }
+
+ for (int j = 0; j < widthMap.get(i) + CELL_PAD_SIZE * 2; j++) {
+ sb.append(CELL_DASH_CHAR);
+ }
+ sb.append(CELL_CORNER_CHAR);
+ }
+ }
+
+ private Map<Integer, Integer> getWidthMap() {
+ Map<Integer, Integer> map = new HashMap<>();
+ String cellValue = null;
+ String headerValue = null;
+
+ // set max's to header sizes for each col
+ for (int i = 0; i < headers.size(); i++) {
+ headerValue = ensureEvenLength(headers.get(i));
+ map.put(i, headerValue.length());
+ }
+ // if there are any cell values longer than the header length set max to longest
+ // cell value length
+ for (List<String> row : rows) {
+ for (int i = 0; i < row.size(); i++) {
+ cellValue = ensureEvenLength(row.get(i));
+ if (map.get(i) == null || cellValue.length() > map.get(i)) {
+ map.put(i, cellValue.length());
+ }
+ }
+ }
+
+ return map;
+ }
+}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxShellTableTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxShellTableTest.java
new file mode 100644
index 0000000..62dd8c9
--- /dev/null
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/KnoxShellTableTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.knox.gateway.shell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+public class KnoxShellTableTest {
+
+ @Test
+ public void testSimpleTableRendering() {
+ String expectedResult = "+------------+------------+------------+\n"
+ + "| Column A | Column B | Column C |\n" + "+------------+------------+------------+\n"
+ + "| 123 | 456 | 3 |\n" + "+------------+------------+------------+\n";
+
+ KnoxShellTable table = new KnoxShellTable();
+
+ table.header("Column A").header("Column B").header("Column C");
+
+ table.row().value("123").value("456").value("3");
+
+ assertEquals(expectedResult, table.toString());
+ }
+
+ @Test
+ public void testValueLongerThanHeader() {
+ String expectedResult = "+------------+------------+--------------+\n"
+ + "| Column A | Column B | Column C |\n" + "+------------+------------+--------------+\n"
+ + "| 123 | 456 | 344444444 |\n" + "+------------+------------+--------------+\n";
+
+ KnoxShellTable table = new KnoxShellTable();
+
+ table.header("Column A").header("Column B").header("Column C");
+
+ table.row().value("123").value("456").value("344444444");
+
+ assertEquals(expectedResult, table.toString());
+
+ }
+
+ @Test
+ public void testMultipleRowsTableRendering() {
+ String expectedResult = "+------------+------------+--------------+\n"
+ + "| Column A | Column B | Column C |\n" + "+------------+------------+--------------+\n"
+ + "| 123 | 456 | 344444444 |\n"
+ + "| 789 | 012 | 844444444 |\n" + "+------------+------------+--------------+\n";
+
+ KnoxShellTable table = new KnoxShellTable();
+
+ table.header("Column A").header("Column B").header("Column C");
+
+ table.row().value("123").value("456").value("344444444");
+ table.row().value("789").value("012").value("844444444");
+
+ assertEquals(expectedResult, table.toString());
+
+ }
+
+ @Test
+ public void testMultipleRowsTableNoHeadersRendering() {
+ String expectedResult = "+--------+--------+--------------+\n"
+ + "| 123 | 456 | 344444444 |\n"
+ + "| 789 | 012 | 844444444 |\n" + "+--------+--------+--------------+\n";
+
+ KnoxShellTable table = new KnoxShellTable();
+
+ table.row().value("123").value("456").value("344444444");
+ table.row().value("789").value("012").value("844444444");
+
+ assertEquals(expectedResult, table.toString());
+
+ }
+
+ @Test
+ public void testMultipleRowsTableMismatchedColAndHeadersCountError() {
+ KnoxShellTable table = new KnoxShellTable();
+
+ table.header("Column A").header("Column B");
+
+ table.row().value("123").value("456").value("344444444");
+ table.row().value("789").value("012").value("844444444");
+
+ try {
+ table.toString();
+ fail("IllegalStateException expected.");
+ }
+ catch (IllegalStateException ise) {
+ // expected
+ }
+ }
+}