1:
43:
44: package ;
45:
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52:
58: public class ObjectTable implements Serializable {
59:
60:
61: private static final long serialVersionUID = -3968322452944912066L;
62:
63:
64: private int rows;
65:
66:
67: private int columns;
68:
69:
70: private transient Object[][] data;
71:
72:
76: private int rowIncrement;
77:
78:
82: private int columnIncrement;
83:
84:
87: public ObjectTable() {
88: this (5, 5);
89: }
90:
91:
96: public ObjectTable(final int increment) {
97: this (increment, increment);
98: }
99:
105: public ObjectTable(final int rowIncrement, final int colIncrement) {
106: if (rowIncrement < 1) {
107: throw new IllegalArgumentException("Increment must be positive.");
108: }
109:
110: if (colIncrement < 1) {
111: throw new IllegalArgumentException("Increment must be positive.");
112: }
113:
114: this.rows = 0;
115: this.columns = 0;
116: this.rowIncrement = rowIncrement;
117: this.columnIncrement = colIncrement;
118:
119: this.data = new Object[rowIncrement][];
120: }
121:
122:
127: public int getColumnIncrement() {
128: return this.columnIncrement;
129: }
130:
131:
136: public int getRowIncrement() {
137: return this.rowIncrement;
138: }
139:
140:
146: protected void ensureRowCapacity (final int row) {
147:
148:
149: if (row >= this.data.length) {
150:
151: final Object[][] enlarged = new Object[row + this.rowIncrement][];
152: System.arraycopy(this.data, 0, enlarged, 0, this.data.length);
153:
154:
155: this.data = enlarged;
156: }
157: }
158:
159:
165: public void ensureCapacity (final int row, final int column) {
166:
167: if (row < 0) {
168: throw new IndexOutOfBoundsException("Row is invalid. " + row);
169: }
170: if (column < 0) {
171: throw new IndexOutOfBoundsException("Column is invalid. " + column);
172: }
173:
174: ensureRowCapacity(row);
175:
176: final Object[] current = this.data[row];
177: if (current == null) {
178: final Object[] enlarged
179: = new Object[Math.max (column + 1, this.columnIncrement)];
180: this.data[row] = enlarged;
181: }
182: else if (column >= current.length) {
183: final Object[] enlarged = new Object[column + this.columnIncrement];
184: System.arraycopy(current, 0, enlarged, 0, current.length);
185: this.data[row] = enlarged;
186: }
187: }
188:
189:
194: public int getRowCount() {
195: return this.rows;
196: }
197:
198:
203: public int getColumnCount() {
204: return this.columns;
205: }
206:
207:
218: protected Object getObject(final int row, final int column) {
219:
220: if (row < this.data.length) {
221: final Object[] current = this.data[row];
222: if (current == null) {
223: return null;
224: }
225: if (column < current.length) {
226: return current[column];
227: }
228: }
229: return null;
230:
231: }
232:
233:
241: protected void setObject(final int row, final int column,
242: final Object object) {
243:
244: ensureCapacity(row, column);
245:
246: this.data[row][column] = object;
247: this.rows = Math.max (this.rows, row + 1);
248: this.columns = Math.max (this.columns, column + 1);
249: }
250:
251:
259: public boolean equals(final Object o) {
260:
261: if (o == null) {
262: return false;
263: }
264:
265: if (this == o) {
266: return true;
267: }
268:
269: if ((o instanceof ObjectTable) == false) {
270: return false;
271: }
272:
273: final ObjectTable ot = (ObjectTable) o;
274: if (getRowCount() != ot.getRowCount()) {
275: return false;
276: }
277:
278: if (getColumnCount() != ot.getColumnCount()) {
279: return false;
280: }
281:
282: for (int r = 0; r < getRowCount(); r++) {
283: for (int c = 0; c < getColumnCount(); c++) {
284: if (ObjectUtilities.equal(getObject(r, c),
285: ot.getObject(r, c)) == false) {
286: return false;
287: }
288: }
289: }
290: return true;
291: }
292:
293:
298: public int hashCode() {
299: int result;
300: result = this.rows;
301: result = 29 * result + this.columns;
302: return result;
303: }
304:
305:
312: private void writeObject(final ObjectOutputStream stream)
313: throws IOException {
314: stream.defaultWriteObject();
315: final int rowCount = this.data.length;
316: stream.writeInt(rowCount);
317: for (int r = 0; r < rowCount; r++) {
318: final Object[] column = this.data[r];
319: stream.writeBoolean(column != null);
320: if (column != null) {
321: final int columnCount = column.length;
322: stream.writeInt(columnCount);
323: for (int c = 0; c < columnCount; c++) {
324: writeSerializedData(stream, column[c]);
325: }
326: }
327: }
328: }
329:
330:
337: protected void writeSerializedData(final ObjectOutputStream stream,
338: final Object o)
339: throws IOException {
340: stream.writeObject(o);
341: }
342:
343:
351: private void readObject(final ObjectInputStream stream)
352: throws IOException, ClassNotFoundException {
353: stream.defaultReadObject();
354: final int rowCount = stream.readInt();
355: this.data = new Object[rowCount][];
356: for (int r = 0; r < rowCount; r++) {
357: final boolean isNotNull = stream.readBoolean();
358: if (isNotNull) {
359: final int columnCount = stream.readInt();
360: final Object[] column = new Object[columnCount];
361: this.data[r] = column;
362: for (int c = 0; c < columnCount; c++) {
363: column[c] = readSerializedData(stream);
364: }
365: }
366: }
367: }
368:
369:
379: protected Object readSerializedData(final ObjectInputStream stream)
380: throws ClassNotFoundException, IOException {
381: return stream.readObject();
382: }
383:
384:
387: public void clear () {
388: this.rows = 0;
389: this.columns = 0;
390: for (int i = 0; i < this.data.length; i++) {
391: if (this.data[i] != null) {
392: Arrays.fill(this.data[i], null);
393: }
394: }
395: }
396:
397:
403: protected void copyColumn (final int oldColumn, final int newColumn)
404: {
405: for (int i = 0; i < getRowCount(); i++)
406: {
407: setObject(i, newColumn, getObject(i, oldColumn));
408: }
409: }
410:
411:
418: protected void copyRow (final int oldRow, final int newRow)
419: {
420: this.ensureCapacity(newRow, getColumnCount());
421: final Object[] oldRowStorage = this.data[oldRow];
422: if (oldRowStorage == null)
423: {
424: final Object[] newRowStorage = this.data[newRow];
425: if (newRowStorage != null)
426: {
427: Arrays.fill(newRowStorage, null);
428: }
429: }
430: else
431: {
432: this.data[newRow] = (Object[]) oldRowStorage.clone();
433: }
434: }
435: }