001: package fit.decorator.util;
002:
003: import java.text.ParseException;
004:
005: import fit.Parse;
006: import fit.decorator.exceptions.InvalidInputException;
007:
008: public class Table {
009: private final Parse table;
010:
011: public Table(Parse table) {
012: this .table = table;
013: }
014:
015: public Table(String html) throws ParseException {
016: this .table = new Parse(html);
017: }
018:
019: public Parse incrementColumnValues(int numberOfTimes,
020: String columnName, Delta delta)
021: throws InvalidInputException {
022: int headerRowIndex = rowNumberContainingText(columnName);
023: copyAndAppendLastRow(numberOfTimes - 1);
024: incrementColumnValues(columnName, delta, headerRowIndex);
025: return table;
026: }
027:
028: public void insertAsFirstRow(Parse firstRow) {
029: firstRow.more = table.parts;
030: table.parts = firstRow;
031: }
032:
033: public Parse stripFirstRow() {
034: Parse firstRow = table.parts;
035: table.parts = table.parts.more;
036: return firstRow;
037: }
038:
039: public String toString() {
040: return toSimpleText(table, new StringBuffer());
041: }
042:
043: int columnNumberContainingText(String columnName, int headerRowIndex)
044: throws InvalidInputException {
045: int columnNumber = -1;
046: Parse columns = table.at(0, headerRowIndex, 0);
047: while (columns != null) {
048: columnNumber++;
049: if (columnName.equals(columns.text())) {
050: return columnNumber;
051: }
052: columns = columns.more;
053: }
054: throw new InvalidInputException(errorMsg(columnName));
055: }
056:
057: String columnValue(int rowIndex, int columnIndex) {
058: return table.at(0, rowIndex, columnIndex).text();
059: }
060:
061: public void copyAndAppendLastRow(int numberOfTimes) {
062: if (numberOfTimes > 0 && tableHasMoreThanTwoRows()) {
063: Parse lastRow = lastRow();
064: Parse secondLastRow = secondLastRow(lastRow);
065: copyAndAppend(lastRow, numberOfTimes);
066: secondLastRow.more = lastRow;
067: }
068: }
069:
070: void incrementColumnValues(String columnName, Delta delta,
071: int headerRowIndex) throws InvalidInputException {
072: int columnNumber = columnNumberContainingText(columnName,
073: headerRowIndex);
074: int totalNumberOfRows = numberOfRows();
075: for (int i = headerRowIndex + 2; i < totalNumberOfRows; ++i) {
076: Parse columnToBeUpdated = table.at(0, i, columnNumber);
077: String value = columnToBeUpdated.text();
078: value = delta.addTo(value, i - headerRowIndex - 1);
079: columnToBeUpdated.body = value;
080: }
081: }
082:
083: Parse lastRow() {
084: return table.parts.last();
085: }
086:
087: int numberOfRows() {
088: return table.parts.size();
089: }
090:
091: int rowNumberContainingText(String searchText)
092: throws InvalidInputException {
093: Parse rows = table.at(0, 0);
094: int numberOfRows = rows.size();
095: for (int i = 0; i < numberOfRows; i++) {
096: Parse columns = table.at(0, i, 0);
097: int numberOfColumns = columns.size();
098: for (int j = 0; j < numberOfColumns; ++j) {
099: if (searchText.equals(table.at(0, i, j).text())) {
100: return i;
101: }
102: }
103: }
104: throw new InvalidInputException(errorMsg(searchText));
105: }
106:
107: Parse secondLastRow(Parse lastRow) {
108: Parse nextRow = table.parts;
109: Parse currentRow = null;
110: while (nextRow != lastRow) {
111: currentRow = nextRow;
112: nextRow = nextRow.more;
113: }
114: currentRow.more = null;
115: return currentRow;
116: }
117:
118: private void copyAndAppend(Parse lastRow, int numberOfTimes) {
119: for (int i = 0; i < numberOfTimes; i++) {
120: Parse columns = lastRow.parts;
121: Parse nextColumn = columns.more;
122: Parse newNextColumn = newParse(nextColumn, nextColumn.more);
123: Parse newColumn = newParse(columns, newNextColumn);
124: Parse newRow = new Parse(stripAngularBrackets(lastRow.tag),
125: lastRow.body, newColumn, null);
126: lastRow.last().more = newRow;
127: }
128: }
129:
130: private Parse newParse(Parse columns, Parse nextColumn) {
131: return new Parse(stripAngularBrackets(columns.tag),
132: columns.body, columns.parts, nextColumn);
133: }
134:
135: private String errorMsg(String searchText) {
136: return "'" + searchText + "' was not found in the table "
137: + toString();
138: }
139:
140: private void simpleTextOfLeave(Parse table, StringBuffer returnText) {
141: returnText.append(table.tag).append(table.text()).append(
142: table.end);
143: }
144:
145: private void simpleTextOfMore(Parse table, StringBuffer returnText) {
146: if ((table.more != null)) {
147: toSimpleText(table.more, returnText);
148: }
149: }
150:
151: private void simpleTextOfParts(Parse table, StringBuffer returnText) {
152: returnText.append(table.tag);
153: toSimpleText(table.parts, returnText);
154: returnText.append(table.end);
155: }
156:
157: private String stripAngularBrackets(String tag) {
158: return tag.substring(1, tag.length() - 1);
159: }
160:
161: private String toSimpleText(Parse table, StringBuffer returnText) {
162: if (table.parts == null) {
163: simpleTextOfLeave(table, returnText);
164: simpleTextOfMore(table, returnText);
165: return returnText.toString();
166: }
167: simpleTextOfParts(table, returnText);
168: simpleTextOfMore(table, returnText);
169: return returnText.toString();
170: }
171:
172: public Parse table() {
173: return table;
174: }
175:
176: public Parse incrementColumnValuesByDelta(String columnName,
177: Delta delta) throws InvalidInputException {
178: int headerRowIndex = rowNumberContainingText(columnName);
179: incrementColumnValues(columnName, delta, headerRowIndex);
180: return table;
181: }
182:
183: private boolean tableHasMoreThanTwoRows() {
184: return (table.parts.size() > 2);
185: }
186: }
|