/*
* JBoss, Home of Professional Open Source.
* Copyright 2015, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.cli.util;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
/**
*
* @author Alexey Loubyansky
*/
public class StrictSizeTable {
private final int rowsTotal;
private final Map<String,Column> columns = new LinkedHashMap<String,Column>();//HashMap<String,Column>();
private int rowIndex = 0;
private int totalWidth;
public StrictSizeTable(int rowsTotal) {
if(rowsTotal <= 0) {
throw new IllegalArgumentException("The number of rows must be bigger than zero: " + rowsTotal);
}
this.rowsTotal = rowsTotal;
}
public boolean isAtLastRow() {
return rowIndex == rowsTotal - 1;
}
public void nextRow() {
if(rowIndex + 1 >= rowsTotal) {
throw new IndexOutOfBoundsException("Row index exceeded table size " + rowsTotal + ": " + rowIndex);
}
++rowIndex;
}
public void addCell(String header, String value) {
if(header == null) {
throw new IllegalArgumentException("Header can't be null.");
}
Column column = columns.get(header);
if(column == null) {
column = new Column(header);
columns.put(header, column);
column.maxWidth = Math.max(header.length() + 1, 4); // for n/a
totalWidth += column.maxWidth;
}
if(value != null) {
column.cells[rowIndex] = value;
if(value.length() + 1 > column.maxWidth) {
totalWidth -= column.maxWidth;
column.maxWidth = value.length() + 1;
totalWidth += column.maxWidth;
}
}
}
public String toString() {
final StringBuilder buf = new StringBuilder((rowsTotal + 1)*totalWidth);
int columnOffset = 0;
Iterator<Column> iter = columns.values().iterator();
while(iter.hasNext()) {
final Column column = iter.next();
if(buf.length() < columnOffset) {
buf.setLength(columnOffset);
}
buf.insert(columnOffset, column.header.toUpperCase(Locale.ENGLISH));
for(int i = column.header.length(); i < column.maxWidth; ++i) {
buf.insert(columnOffset + i, ' ');
}
if(columnOffset == 0) {
buf.insert(column.maxWidth, '\n');
}
for(int i = 0; i < rowsTotal; ++i) {
final int offset = (i + 1)*(columnOffset + column.maxWidth + 1) + columnOffset;
if(buf.length() < offset) {
buf.setLength(offset);
}
String value = column.cells[i];
if(value == null) {
value = "n/a";
}
buf.insert(offset, value);
for(int j = value.length(); j < column.maxWidth; ++j) {
buf.insert(offset + j, ' ');
}
if(columnOffset == 0) {
buf.insert(offset + column.maxWidth, '\n');
}
}
columnOffset += column.maxWidth;
}
return buf.toString();
}
public boolean isEmpty() {
return columns.isEmpty();
}
private class Column {
final String header;
final String[] cells = new String[rowsTotal];
int maxWidth;
Column(String header) {
this.header = header;
}
}
public static void main(String[] args) throws Exception {
StrictSizeTable t = new StrictSizeTable(4);
t.addCell("h1", "r1 h1");
t.nextRow();
t.addCell("h1", "r2 h1");
t.addCell("h2", "r2 h2");
t.nextRow();
t.addCell("h2", "r3 h2");
t.nextRow();
t.addCell("h3", "r4 h3");
System.out.println(t.toString());
}
}