package nl.improved.sqlclient.util;
import java.awt.event.ActionEvent;
import java.util.*;
public class ResultBuilder {
public enum Alignment {LEFT, RIGHT};
private Map<Integer, Integer> columnSizes = new HashMap<Integer, Integer>();
private List<String> header;
private CharSequence footer;
private boolean horizontalSeperatorEnabled = true;
private char horizontalSeperator = '-', verticalSeparator ='|';
private RowList rows = new RowList();
public void setHorizontalSeparatorEnabled(boolean enabled) {
this.horizontalSeperatorEnabled = enabled;
}
public boolean getHorizontalSeparatorEnabled() {
return horizontalSeperatorEnabled;
}
public void setHorizontalSeparator(char c) {
this.horizontalSeperator = c;
}
public char getHorizontalSeparator() {
return horizontalSeperator;
}
public void setVerticalSeparator(char c) {
this.verticalSeparator = c;
}
public char getVerticalSeparator() {
return verticalSeparator;
}
public void setHeader(List<String> columnNames) {
this.header = columnNames;
for (int column = 0; column < columnNames.size(); column++) {
Integer maxValue = columnSizes.get(new Integer(column));
if (maxValue == null || maxValue.intValue() < columnNames.get(column).length()) {
columnSizes.put(new Integer(column), columnNames.get(column).length());
}
}
}
public void setFooter(CharSequence footer) {
this.footer = footer;
}
public void set(int column,int row, CharSequence s) {
set(column,row, s, Alignment.LEFT);
}
public void set(int column,int row, CharSequence s, Alignment alignment) {
rows.setValue(column, row, s, alignment);
}
@Override
public String toString() {
int rowLength = 2; //add |<row>\n
for (int col = 0; col <= rows.columnCount; col++) {
Integer colSize = columnSizes.get(col);
if (colSize != null) {
rowLength += colSize.intValue() + 1; // add |
}
}
int probableLength = (rowLength * (rows.rowCount + 2 + (header == null ? 0 : 1))) + (footer == null ? 0 : footer.length()+1) + 500;
StringBuilder result = new StringBuilder(probableLength);
if (header != null) {
if (horizontalSeperatorEnabled) {
for (int i = 0; i < rowLength-1; i++) {
result.append(horizontalSeperator);
}
}
result.append('\n');
result.append(verticalSeparator);
for (int i = 0; i < header.size(); i++) {
result.append(header.get(i));
Integer colSize = columnSizes.get(i);
if (colSize != null) {
int colSizeInt = colSize.intValue();
for (int tmp = header.get(i).length(); tmp < colSizeInt; tmp++) {
result.append(' ');
}
result.append(verticalSeparator);
}
}
result.append('\n');
}
if (horizontalSeperatorEnabled) {
for (int i = 0; i < rowLength-1; i++) {
result.append(horizontalSeperator);
}
}
result.append('\n');
Iterator<Cell> cells = rows.iterator();
int prevRow = 0;
result.append(verticalSeparator);
while (cells.hasNext()) {
Cell cell = cells.next();
if (cell != null && cell.row != prevRow) {
result.append('\n');
result.append(verticalSeparator);
prevRow = cell.row;
}
int colStart = result.length();
int spaceUsed = 0;
if (cell != null) {
result.append(cell.getValue());
spaceUsed = cell.getLength();
Integer colSize = columnSizes.get(cell.col);
if (colSize != null) {
int colSizeInt = colSize.intValue();
for (int i = spaceUsed; i < colSizeInt; i++) {
if (cell == null || cell.getAlignment() == Alignment.LEFT) {
result.append(' ');
} else {
result.insert(colStart, ' ');
}
}
result.append(verticalSeparator);
}
}
}
result.append('\n');
if (horizontalSeperatorEnabled) {
for (int i = 0; i < rowLength-1; i++) {
result.append(horizontalSeperator);
}
}
result.append('\n');
if (footer != null) {
result.append(footer);
result.append('\n');
}
return result.toString();
}
private static class Cell {
private int row, col;
private CharSequence buffer;
private Alignment alignment;
public Cell(int col, int row, CharSequence value, Alignment alignment) {
this.col = col;
this.row = row;
buffer = value;
this.alignment = alignment;
}
public int getRow() {
return row;
}
public int getColumn() {
return col;
}
public Alignment getAlignment() {
return alignment;
}
public void setValue(CharSequence s) {
buffer = s;
}
public CharSequence getValue() {
return buffer;
}
public int getLength() {
return buffer.length();
}
@Override
public int hashCode() {
return row + col;
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
Cell c= (Cell)o;
return c.row == row && c.col == col;
}
}
private class RowList {
private int columnCount = 0, rowCount = 0;
private Row firstRow = null;
private Row lastRow = null;
public RowList() {
}
public void setValue(int col, int row, CharSequence value, Alignment align) {
// TODO remove first row(s) when rowsize larger then maxsize
columnCount = Math.max(columnCount, col);
rowCount = Math.max(rowCount, row);
Row newRow;
if (firstRow == null) {
firstRow = new Row(row);
lastRow = firstRow;
newRow = firstRow;
} else if (lastRow.rowNum == row) {
newRow = lastRow;
} else if (lastRow.rowNum < row) {
lastRow.nextRow = new Row(row);
newRow = lastRow.nextRow;
lastRow = newRow;
} else {
throw new IllegalStateException("Please add rows in order!");
}
Cell c = new Cell(col, row, value, align);
if (newRow.cells.contains(c)) {
newRow.cells.remove(c);
}
newRow.cells.add(c);
Integer maxValue = columnSizes.get(new Integer(col));
if (maxValue == null || maxValue.intValue() < c.getLength()+1) { // +1 because one space at end of column
columnSizes.put(new Integer(col), c.getLength()+1);
}
}
public Iterator<Cell> iterator() {
Iterator<Cell> i = new Iterator<Cell>() {
Row curRow = firstRow;
int colNr = 0;
@Override
public boolean hasNext() {
return curRow != null && ((colNr <= columnCount) || curRow.nextRow != null);
}
@Override
public Cell next() {
if (colNr > columnCount) {
colNr = 0;
curRow = curRow.nextRow;
}
return curRow.getCell(colNr++);
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
};
return i;
}
private class Row {
public Row nextRow;
public int rowNum;
public List<Cell> cells;
public Row(int rowNum) {
this.rowNum = rowNum;
cells = new ArrayList<Cell>();
}
Cell getCell(int col) {
Cell c;
if (cells.size() > col) {
c = cells.get(col);
if (c.col == col) {
return c;
}
}
Iterator<Cell> iCells = cells.iterator();
while (iCells.hasNext()) {
c = iCells.next();
if (c.col == col) {
return c;
}
}
return null;
}
}
}
public static void main(String[] args) throws Exception {
ResultBuilder builder = new ResultBuilder();
builder.set(0, 0, "faaaaaa");
builder.set(1, 0, "fbbbbbb");
builder.set(2, 0, "fcccccc");
builder.set(3, 0, "fdddddd");
builder.set(4, 0, "feeeeee");
for (int row = 1; row < 2000; row++) {
builder.set(0, row, "aaaaaaa");
builder.set(1, row, "bbbbbbb");
builder.set(2, row, "ccccccc");
builder.set(3, row, "ddddddd");
builder.set(4, row, "eeeeeee");
}
builder.set(0, 2000, "laaaaaa");
builder.set(1, 2000, "lbbbbbb");
builder.set(2, 2000, "lcccccc");
builder.set(3, 2000, "ldddddd");
builder.set(4, 2000, "leeeeee");
long start = System.currentTimeMillis();
System.out.println(builder.toString());
System.out.println("TIME: "+ (System.currentTimeMillis() - start));
}
}
|