/** * Copyright 2016 Yahoo Inc. * * Licensed 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 com.yahoo.pulsar.testclient.utils; import java.util.Objects; import java.util.function.Function; /** * Light-weight utility for creating rows where each column has a fixed length in a command-line setting. */ public class FixedColumnLengthTableMaker { /** * Character to duplicate to make the bottom border. */ public char bottomBorder = '='; /** * Format String to apply to decimal entries. If set to null, no special formatting is applied. */ public String decimalFormatter = null; /** * Length of table elements. Elements whose String representations exceed this length are trimmed down to this * length. */ public int elementLength = 10; /** * The border to use to make the left side of the table. */ public String leftBorder = "||"; /** * The amount of spacing to pad left of an element with. */ public int leftPadding = 0; /** * The border to use to make the right side of the table. */ public String rightBorder = "||"; /** * The amount of spacing to pad right of an element with. */ public int rightPadding = 1; /** * The String to separate elements with. */ public String separator = "|"; /** * Character to duplicate to make the top border. */ public char topBorder = '='; /** * If not null, lengthFunction should give the length for the given column index. */ public Function<Integer, Integer> lengthFunction = null; // Helper function to add top and bottom borders. private void addHorizontalBorder(final int length, final StringBuilder builder, final char borderChar) { for (int i = 0; i < length; ++i) { builder.append(borderChar); } } // Helper function to pad with white space. private void addSpace(final int amount, final StringBuilder builder) { for (int i = 0; i < amount; ++i) { builder.append(' '); } } private int lengthFor(final int column) { return lengthFunction == null ? elementLength : lengthFunction.apply(column); } /** * Make a table using the specified settings. * * @param rows * Rows to construct the table from. * @return A String version of the table. */ public String make(final Object[][] rows) { final StringBuilder builder = new StringBuilder(); int numColumns = 0; for (final Object[] row : rows) { // Take the largest number of columns out of any row to be the total. numColumns = Math.max(numColumns, row.length); } // Total length of the table in characters. int totalLength = numColumns * (leftPadding + rightPadding + separator.length()) - separator.length() + leftBorder.length() + rightBorder.length(); for (int i = 0; i < numColumns; ++i) { totalLength += lengthFor(i); } addHorizontalBorder(totalLength, builder, topBorder); builder.append('\n'); int i; for (final Object[] row : rows) { i = 0; builder.append(leftBorder); for (final Object element : row) { addSpace(leftPadding, builder); String elementString; if ((element instanceof Float || element instanceof Double) && decimalFormatter != null) { elementString = String.format(decimalFormatter, element); } else { // Avoid throwing NPE elementString = Objects.toString(element, ""); } if (elementString.length() > lengthFor(i)) { // Trim down to the maximum number of characters. elementString = elementString.substring(0, lengthFor(i)); } builder.append(elementString); // Add the space due to remaining characters and the right padding. addSpace(lengthFor(i) - elementString.length() + rightPadding, builder); if (i != numColumns - 1) { // Don't add separator for the last column. builder.append(separator); } i += 1; } // Put empty elements for remaining columns. for (; i < numColumns; ++i) { addSpace(leftPadding + rightPadding + lengthFor(i), builder); if (i != numColumns - 1) { builder.append(separator); } } builder.append(rightBorder); builder.append('\n'); } addHorizontalBorder(totalLength, builder, bottomBorder); return builder.toString(); } }