01: package jimm.datavision.source;
02:
03: import java.util.List;
04:
05: /**
06: * Represents a row of data. Provides the interface needed by
07: * <code>Report</code>, no more. When using JDBC, this is a wrapper around
08: * a <code>ResultSet</code>.
09: * <p>
10: * The only method subclasses <em>must</em> implement is
11: * <code>readRowData()</code>.
12: *
13: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
14: */
15: public abstract class DataCursor {
16:
17: protected int currRowNumber; // Starts at 1
18: protected List prevRowData;
19: protected List currRowData;
20: protected List nextRowData;
21: protected List lastRowData;
22: protected int lastRowNumber;
23:
24: public boolean isFirst() {
25: return currRowNumber == 1;
26: }
27:
28: public boolean isLast() {
29: if (nextRowData != null) // We already have next row cached
30: return false;
31: nextRowData = readRowData(); // Read next row
32: return nextRowData == null; // If it's null, we are at the last row
33: }
34:
35: public boolean next() {
36: if (nextRowData == null) // If we have no cached data, read the next row
37: nextRowData = readRowData();
38:
39: if (nextRowData == null) { // When no more data, curr row is the last row
40: lastRowData = currRowData;
41: lastRowNumber = currRowNumber;
42: }
43:
44: prevRowData = currRowData;
45: currRowData = nextRowData;
46: nextRowData = null;
47:
48: ++currRowNumber;
49: return currRowData != null;
50: }
51:
52: public boolean previous() {
53: if (currRowNumber <= 1) // Not same as isFirst()
54: return false;
55:
56: nextRowData = currRowData;
57: currRowData = prevRowData;
58: prevRowData = null;
59: --currRowNumber;
60: return true;
61: }
62:
63: public boolean last() {
64: while (lastRowData == null && next())
65: ;
66: currRowData = lastRowData;
67: currRowNumber = lastRowNumber;
68: return true;
69: }
70:
71: public int getRow() {
72: return currRowNumber;
73: }
74:
75: public void close() {
76: }
77:
78: /**
79: * Returns the object in the specified column. <var>index</var> starts
80: * at 1.
81: * <p>
82: * Even when running a report, <var>currRowData</var> is not always
83: * defined. For example, when a query returns zero rows but a column field
84: * is in some header or footer, this method is called but
85: * <var>currRowData</var> is <code>null</code>. If it is, we return
86: * <code>null</code>.
87: *
88: * @return the object in the <var>index</var>'th column, or <code>null</code>
89: * if no data has yet been read
90: */
91: public Object getObject(int index) {
92: return currRowData == null ? null : currRowData.get(index - 1);
93: }
94:
95: protected abstract List readRowData();
96:
97: }
|