001: package nl.improved.sqlclient.util;
002:
003: import java.awt.event.ActionEvent;
004: import java.util.*;
005:
006: public class ResultBuilder {
007:
008: public enum Alignment {
009: LEFT, RIGHT
010: };
011:
012: private Map<Integer, Integer> columnSizes = new HashMap<Integer, Integer>();
013: private List<String> header;
014: private CharSequence footer;
015:
016: private boolean horizontalSeperatorEnabled = true;
017: private char horizontalSeperator = '-', verticalSeparator = '|';
018: private RowList rows = new RowList();
019:
020: public void setHorizontalSeparatorEnabled(boolean enabled) {
021: this .horizontalSeperatorEnabled = enabled;
022: }
023:
024: public boolean getHorizontalSeparatorEnabled() {
025: return horizontalSeperatorEnabled;
026: }
027:
028: public void setHorizontalSeparator(char c) {
029: this .horizontalSeperator = c;
030: }
031:
032: public char getHorizontalSeparator() {
033: return horizontalSeperator;
034: }
035:
036: public void setVerticalSeparator(char c) {
037: this .verticalSeparator = c;
038: }
039:
040: public char getVerticalSeparator() {
041: return verticalSeparator;
042: }
043:
044: public void setHeader(List<String> columnNames) {
045: this .header = columnNames;
046: for (int column = 0; column < columnNames.size(); column++) {
047: Integer maxValue = columnSizes.get(new Integer(column));
048: if (maxValue == null
049: || maxValue.intValue() < columnNames.get(column)
050: .length()) {
051: columnSizes.put(new Integer(column), columnNames.get(
052: column).length());
053: }
054: }
055: }
056:
057: public void setFooter(CharSequence footer) {
058: this .footer = footer;
059: }
060:
061: public void set(int column, int row, CharSequence s) {
062: set(column, row, s, Alignment.LEFT);
063: }
064:
065: public void set(int column, int row, CharSequence s,
066: Alignment alignment) {
067: rows.setValue(column, row, s, alignment);
068: }
069:
070: @Override
071: public String toString() {
072: int rowLength = 2; //add |<row>\n
073: for (int col = 0; col <= rows.columnCount; col++) {
074: Integer colSize = columnSizes.get(col);
075: if (colSize != null) {
076: rowLength += colSize.intValue() + 1; // add |
077: }
078: }
079:
080: int probableLength = (rowLength * (rows.rowCount + 2 + (header == null ? 0
081: : 1)))
082: + (footer == null ? 0 : footer.length() + 1) + 500;
083: StringBuilder result = new StringBuilder(probableLength);
084: if (header != null) {
085: if (horizontalSeperatorEnabled) {
086: for (int i = 0; i < rowLength - 1; i++) {
087: result.append(horizontalSeperator);
088: }
089: }
090: result.append('\n');
091: result.append(verticalSeparator);
092: for (int i = 0; i < header.size(); i++) {
093: result.append(header.get(i));
094: Integer colSize = columnSizes.get(i);
095: if (colSize != null) {
096: int colSizeInt = colSize.intValue();
097: for (int tmp = header.get(i).length(); tmp < colSizeInt; tmp++) {
098: result.append(' ');
099: }
100: result.append(verticalSeparator);
101: }
102: }
103: result.append('\n');
104: }
105: if (horizontalSeperatorEnabled) {
106: for (int i = 0; i < rowLength - 1; i++) {
107: result.append(horizontalSeperator);
108: }
109: }
110: result.append('\n');
111: Iterator<Cell> cells = rows.iterator();
112: int prevRow = 0;
113: result.append(verticalSeparator);
114: while (cells.hasNext()) {
115: Cell cell = cells.next();
116: if (cell != null && cell.row != prevRow) {
117: result.append('\n');
118: result.append(verticalSeparator);
119: prevRow = cell.row;
120: }
121: int colStart = result.length();
122: int spaceUsed = 0;
123: if (cell != null) {
124: result.append(cell.getValue());
125: spaceUsed = cell.getLength();
126:
127: Integer colSize = columnSizes.get(cell.col);
128: if (colSize != null) {
129: int colSizeInt = colSize.intValue();
130: for (int i = spaceUsed; i < colSizeInt; i++) {
131: if (cell == null
132: || cell.getAlignment() == Alignment.LEFT) {
133: result.append(' ');
134: } else {
135: result.insert(colStart, ' ');
136: }
137: }
138: result.append(verticalSeparator);
139: }
140: }
141: }
142: result.append('\n');
143: if (horizontalSeperatorEnabled) {
144: for (int i = 0; i < rowLength - 1; i++) {
145: result.append(horizontalSeperator);
146: }
147: }
148: result.append('\n');
149: if (footer != null) {
150: result.append(footer);
151: result.append('\n');
152: }
153: return result.toString();
154: }
155:
156: private static class Cell {
157: private int row, col;
158: private CharSequence buffer;
159: private Alignment alignment;
160:
161: public Cell(int col, int row, CharSequence value,
162: Alignment alignment) {
163: this .col = col;
164: this .row = row;
165: buffer = value;
166: this .alignment = alignment;
167: }
168:
169: public int getRow() {
170: return row;
171: }
172:
173: public int getColumn() {
174: return col;
175: }
176:
177: public Alignment getAlignment() {
178: return alignment;
179: }
180:
181: public void setValue(CharSequence s) {
182: buffer = s;
183: }
184:
185: public CharSequence getValue() {
186: return buffer;
187: }
188:
189: public int getLength() {
190: return buffer.length();
191: }
192:
193: @Override
194: public int hashCode() {
195: return row + col;
196: }
197:
198: @Override
199: public boolean equals(Object o) {
200: if (o == null)
201: return false;
202: Cell c = (Cell) o;
203: return c.row == row && c.col == col;
204: }
205: }
206:
207: private class RowList {
208: private int columnCount = 0, rowCount = 0;
209:
210: private Row firstRow = null;
211: private Row lastRow = null;
212:
213: public RowList() {
214: }
215:
216: public void setValue(int col, int row, CharSequence value,
217: Alignment align) {
218: // TODO remove first row(s) when rowsize larger then maxsize
219: columnCount = Math.max(columnCount, col);
220: rowCount = Math.max(rowCount, row);
221: Row newRow;
222: if (firstRow == null) {
223: firstRow = new Row(row);
224: lastRow = firstRow;
225: newRow = firstRow;
226: } else if (lastRow.rowNum == row) {
227: newRow = lastRow;
228: } else if (lastRow.rowNum < row) {
229: lastRow.nextRow = new Row(row);
230: newRow = lastRow.nextRow;
231: lastRow = newRow;
232: } else {
233: throw new IllegalStateException(
234: "Please add rows in order!");
235: }
236:
237: Cell c = new Cell(col, row, value, align);
238: if (newRow.cells.contains(c)) {
239: newRow.cells.remove(c);
240: }
241: newRow.cells.add(c);
242: Integer maxValue = columnSizes.get(new Integer(col));
243: if (maxValue == null
244: || maxValue.intValue() < c.getLength() + 1) { // +1 because one space at end of column
245: columnSizes.put(new Integer(col), c.getLength() + 1);
246: }
247: }
248:
249: public Iterator<Cell> iterator() {
250: Iterator<Cell> i = new Iterator<Cell>() {
251: Row curRow = firstRow;
252: int colNr = 0;
253:
254: @Override
255: public boolean hasNext() {
256: return curRow != null
257: && ((colNr <= columnCount) || curRow.nextRow != null);
258: }
259:
260: @Override
261: public Cell next() {
262: if (colNr > columnCount) {
263: colNr = 0;
264: curRow = curRow.nextRow;
265: }
266: return curRow.getCell(colNr++);
267: }
268:
269: @Override
270: public void remove() {
271: throw new UnsupportedOperationException(
272: "Not supported.");
273: }
274: };
275: return i;
276: }
277:
278: private class Row {
279: public Row nextRow;
280: public int rowNum;
281: public List<Cell> cells;
282:
283: public Row(int rowNum) {
284: this .rowNum = rowNum;
285: cells = new ArrayList<Cell>();
286: }
287:
288: Cell getCell(int col) {
289: Cell c;
290: if (cells.size() > col) {
291: c = cells.get(col);
292: if (c.col == col) {
293: return c;
294: }
295: }
296: Iterator<Cell> iCells = cells.iterator();
297: while (iCells.hasNext()) {
298: c = iCells.next();
299: if (c.col == col) {
300: return c;
301: }
302: }
303: return null;
304: }
305: }
306: }
307:
308: public static void main(String[] args) throws Exception {
309: ResultBuilder builder = new ResultBuilder();
310: builder.set(0, 0, "faaaaaa");
311: builder.set(1, 0, "fbbbbbb");
312: builder.set(2, 0, "fcccccc");
313: builder.set(3, 0, "fdddddd");
314: builder.set(4, 0, "feeeeee");
315: for (int row = 1; row < 2000; row++) {
316: builder.set(0, row, "aaaaaaa");
317: builder.set(1, row, "bbbbbbb");
318: builder.set(2, row, "ccccccc");
319: builder.set(3, row, "ddddddd");
320: builder.set(4, row, "eeeeeee");
321: }
322: builder.set(0, 2000, "laaaaaa");
323: builder.set(1, 2000, "lbbbbbb");
324: builder.set(2, 2000, "lcccccc");
325: builder.set(3, 2000, "ldddddd");
326: builder.set(4, 2000, "leeeeee");
327: long start = System.currentTimeMillis();
328: System.out.println(builder.toString());
329: System.out.println("TIME: "
330: + (System.currentTimeMillis() - start));
331: }
332: }
|