com.gemstone.gemfire.management.internal.cli.result.TableBuilder Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* 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. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.management.internal.cli.result;
/**
* Helper class to build rows of columnized strings & build a table from those
* rows.
*
* Sample usage:
*
*
* public final Table createTable() {
* Table resultTable = TableBuilder.newTable();
* resultTable.setColumnSeparator(" | ");
*
* resultTable.newBlankRow();
* resultTable.newRow().newLeftCol("Displaying all fields for member: " + memberName);
* resultTable.newBlankRow();
* RowGroup rowGroup = resultTable.newRowGroup();
* rowGroup.newRow().newCenterCol("FIELD1").newCenterCol("FIELD2");
* rowGroup.newRowSeparator('-');
* for (int i = 0; i < counter; i++) {
* rowGroup.newRow().newLeftCol(myFirstField[i]).newLeftCol(mySecondField[i]);
* }
* resultTable.newBlankRow();
*
* return resultTable;
* }
*
*
* Will result in this:
*
*
*
* Displaying all fields for member: Member1
*
* FIELD1 | FIELD2
* -------------- | ---------------
* My First Field | My Second Field
* Another Fld1 | Another Fld2
* Last Fld1 | Last Fld2
*
*
*
* @author David Hoots
*
* @since 7.0
*/
import java.util.ArrayList;
import java.util.List;
import com.gemstone.gemfire.management.internal.cli.GfshParser;
public class TableBuilder {
public static Table newTable() {
return new Table();
}
public static class Table {
private final List rowGroups = new ArrayList();
private String columnSeparator = " ";
public void setColumnSeparator(final String columnSeparator) {
this.columnSeparator = columnSeparator;
}
public String getColumnSeparator() {
return this.columnSeparator;
}
public RowGroup newRowGroup() {
RowGroup rowGroup = new RowGroup(this);
this.rowGroups.add(rowGroup);
return rowGroup;
}
public Row newRow() {
RowGroup rowGroup = newRowGroup();
return rowGroup.newRow();
}
public void newBlankRow() {
RowGroup rowGroup = newRowGroup();
rowGroup.newBlankRow();
}
/**
* Computes total Max Row Length across table - for all row groups.
*/
private int getMaxLength() {
int rowGroupMaxTotalLength = 0;
for (RowGroup rowGroup : this.rowGroups) {
List rows = rowGroup.rows;
int rowGroupTotalLength = 0;
int rowMaxTotalLength = 0;
for (Row row : rows) {
int rowTotalLength = 0;
for (int i = 0; i < row.getNumCols(); i++) {
rowTotalLength += row.getMaxColLength(i);
}
if (rowGroup.getColumnSeparator() != null) {
rowTotalLength += row.getNumCols() * rowGroup.getColumnSeparator().length();
}
if (rowMaxTotalLength < rowTotalLength) {
rowMaxTotalLength = rowTotalLength;
}
}
rowGroupTotalLength += rowMaxTotalLength;
if (rowGroupMaxTotalLength < rowGroupTotalLength) {
rowGroupMaxTotalLength = rowGroupTotalLength;
}
}
return (int)(rowGroupMaxTotalLength * 1.1);
}
public String buildTable() {
StringBuffer stringBuffer = new StringBuffer();
for (RowGroup rowGroup : this.rowGroups) {
stringBuffer.append(rowGroup.buildRowGroup());
}
return stringBuffer.toString();
}
public List buildTableList() {
List list = new ArrayList();
for (RowGroup rowGroup : this.rowGroups) {
list.add(rowGroup.buildRowGroup());
}
return list;
}
@Override
public String toString() {
return "Table [rowGroups=" + rowGroups + "]";
}
}
/**
* A group of rows. Widths for all columns within a group will be the same and
* when built will automatically be set to the length of the longest value in
* the column.
*
* @author David Hoots
* @since 7.0
*/
public static class RowGroup {
private final Table table;
private final List rows = new ArrayList();
private int[] colSizes;
private String columnSeparator;
private RowGroup(final Table table) {
this.table = table;
}
private Table getTable() {
return this.table;
}
public Row newRow() {
Row row = new Row(this);
rows.add(row);
return row;
}
public void newRowSeparator(Character character, boolean isTablewideSeparator) {
Row row = new Row(this, character, isTablewideSeparator);
rows.add(row);
}
public void newBlankRow() {
Row row = newRow();
row.newCenterCol("");
row.isBlank = true;
}
public String buildRowGroup() {
this.colSizes = computeColSizes();
StringBuffer stringBuffer = new StringBuffer();
for (Row row : rows) {
String builtRow = row.buildRow();
stringBuffer.append(builtRow);
if (!builtRow.trim().isEmpty() || row.isBlank) {
stringBuffer.append(GfshParser.LINE_SEPARATOR);
}
}
return stringBuffer.toString();
}
private int getColSize(final int colNum) {
return this.colSizes[colNum];
}
private int[] computeColSizes() {
final int[] localColSizes = new int[getNumCols()];
for (int i = 0; i < localColSizes.length; i++) {
localColSizes[i] = getMaxColLength(i);
}
return localColSizes;
}
private int getNumCols() {
int maxNumCols = 0;
for (Row row : rows) {
int numCols = row.getNumCols();
if (numCols > maxNumCols) {
maxNumCols = numCols;
}
}
return maxNumCols;
}
private int getMaxColLength(final int colNum) {
int maxLength = 0;
for (Row row : rows) {
int colLength = row.getMaxColLength(colNum);
if (colLength > maxLength) {
maxLength = colLength;
}
}
return maxLength;
}
public void setColumnSeparator(final String columnSeparator) {
this.columnSeparator = columnSeparator;
}
public String getColumnSeparator() {
return this.columnSeparator != null ? this.columnSeparator : table.getColumnSeparator();
}
@Override
public String toString() {
return "RowGroup [rows=" + rows + "]";
}
}
public static class Row {
private final RowGroup rowGroup;
private final Character rowSeparator;
private final List columns = new ArrayList();
boolean isBlank;
private boolean isTablewideSeparator;
private String columnSeparator;
private Row(final RowGroup rowGroup) {
this.rowGroup = rowGroup;
this.rowSeparator = null;
}
private Row(final RowGroup rowGroup, final Character rowSeparator, final boolean isTablewideSeparator) {
this.rowGroup = rowGroup;
this.rowSeparator = rowSeparator;
this.isTablewideSeparator = isTablewideSeparator;
}
public Row newLeftCol(Object value) {
Column column = new Column(value, Align.LEFT);
this.columns.add(column);
return this;
}
public Row newRightCol(Object value) {
Column column = new Column(value, Align.RIGHT);
this.columns.add(column);
return this;
}
public Row newCenterCol(Object value) {
Column column = new Column(value, Align.CENTER);
this.columns.add(column);
return this;
}
public boolean isEmpty() {
return columns.isEmpty();
}
private int getNumCols() {
return this.columns.size();
}
private int getMaxColLength(final int colNum) {
if (colNum >= this.columns.size())
return 0;
return this.columns.get(colNum).getLength();
}
public void setColumnSeparator(final String columnSeparator) {
this.columnSeparator = columnSeparator;
}
public String getColumnSeparator() {
return this.columnSeparator != null ? this.columnSeparator : rowGroup.getColumnSeparator();
}
private String buildRow() {
StringBuffer stringBuffer = new StringBuffer();
if (this.rowSeparator != null) {
if (isTablewideSeparator) {
int maxColLength = this.rowGroup.getTable().getMaxLength();
for (int j = 0; j < maxColLength; j++) {
stringBuffer.append(this.rowSeparator);
}
} else {
int maxNumCols = this.rowGroup.getNumCols();
for (int i = 0; i < maxNumCols; i++) {
int maxColLength = this.rowGroup.getMaxColLength(i);
for (int j = 0; j < maxColLength; j++) {
stringBuffer.append(this.rowSeparator);
}
if (i < (maxNumCols - 1)) {
stringBuffer.append(this.rowGroup.getColumnSeparator());
}
}
}
} else {
// saj hook
for (int i = 0; i < this.columns.size(); i++) {
boolean lastColumn = !(i < (this.columns.size() - 1));
stringBuffer.append(this.columns.get(i).buildColumn(
this.rowGroup.getColSize(i), lastColumn));
if (!lastColumn) {
stringBuffer.append(getColumnSeparator());
}
}
}
return stringBuffer.toString();
}
@Override
public String toString() {
return "Row [columns=" + columns + "]";
}
}
private static enum Align {
LEFT, RIGHT, CENTER;
};
private static class Column {
private final Align align;
private final String stringValue;
private Column(final Object value, final Align align) {
if (value == null) {
this.stringValue = "";
} else {
this.stringValue = value.toString();
}
this.align = align;
}
private int getLength() {
return this.stringValue.length();
}
private String buildColumn(int colWidth, boolean trimIt) {
int numSpaces = colWidth - this.stringValue.length();
if(trimIt) numSpaces=0;
StringBuffer stringBuffer = new StringBuffer();
switch (align) {
case LEFT:
stringBuffer.append(stringValue);
for (int i = 0; i < numSpaces; i++) {
stringBuffer.append(" ");
}
break;
case RIGHT:
for (int i = 0; i < numSpaces; i++) {
stringBuffer.append(" ");
}
stringBuffer.append(stringValue);
break;
case CENTER:
int i = 0;
for (; i < numSpaces / 2; i++) {
stringBuffer.append(" ");
}
stringBuffer.append(stringValue);
for (; i < numSpaces; i++) {
stringBuffer.append(" ");
}
break;
}
return stringBuffer.toString();
}
private String buildColumn(int colWidth) {
return buildColumn(colWidth, false);
}
@Override
public String toString() {
return "Column [align=" + align + ", stringValue=" + stringValue + "]";
}
}
}