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:
64: private static final long serialVersionUID = -3968322452944912066L;
65:
66:
69: private int rows;
70:
71:
74: private int columns;
75:
76:
79: private transient Object[][] data;
80:
81:
85: private int rowIncrement;
86:
87:
91: private int columnIncrement;
92:
93:
96: public ObjectTable()
97: {
98: this(5, 5);
99: }
100:
101:
106: public ObjectTable(final int increment)
107: {
108: this(increment, increment);
109: }
110:
111:
117: public ObjectTable(final int rowIncrement, final int colIncrement)
118: {
119: if (rowIncrement < 1)
120: {
121: throw new IllegalArgumentException("Increment must be positive.");
122: }
123:
124: if (colIncrement < 1)
125: {
126: throw new IllegalArgumentException("Increment must be positive.");
127: }
128:
129: this.rows = 0;
130: this.columns = 0;
131: this.rowIncrement = rowIncrement;
132: this.columnIncrement = colIncrement;
133:
134: this.data = new Object[rowIncrement][];
135: }
136:
137:
142: public int getColumnIncrement()
143: {
144: return this.columnIncrement;
145: }
146:
147:
152: public int getRowIncrement()
153: {
154: return this.rowIncrement;
155: }
156:
157:
163: protected void ensureRowCapacity(final int row)
164: {
165:
166:
167: if (row >= this.data.length)
168: {
169:
170: final Object[][] enlarged = new Object[row + this.rowIncrement][];
171: System.arraycopy(this.data, 0, enlarged, 0, this.data.length);
172:
173:
174: this.data = enlarged;
175: }
176: }
177:
178:
184: public void ensureCapacity(final int row, final int column)
185: {
186:
187: if (row < 0)
188: {
189: throw new IndexOutOfBoundsException("Row is invalid. " + row);
190: }
191: if (column < 0)
192: {
193: throw new IndexOutOfBoundsException("Column is invalid. " + column);
194: }
195:
196: ensureRowCapacity(row);
197:
198: final Object[] current = this.data[row];
199: if (current == null)
200: {
201: final Object[] enlarged
202: = new Object[Math.max(column + 1, this.columnIncrement)];
203: this.data[row] = enlarged;
204: }
205: else if (column >= current.length)
206: {
207: final Object[] enlarged = new Object[column + this.columnIncrement];
208: System.arraycopy(current, 0, enlarged, 0, current.length);
209: this.data[row] = enlarged;
210: }
211: }
212:
213:
218: public int getRowCount()
219: {
220: return this.rows;
221: }
222:
223:
228: public int getColumnCount()
229: {
230: return this.columns;
231: }
232:
233:
243: protected Object getObject(final int row, final int column)
244: {
245:
246: if (row < this.data.length)
247: {
248: final Object[] current = this.data[row];
249: if (current == null)
250: {
251: return null;
252: }
253: if (column < current.length)
254: {
255: return current[column];
256: }
257: }
258: return null;
259:
260: }
261:
262:
270: protected void setObject(final int row, final int column,
271: final Object object)
272: {
273:
274: ensureCapacity(row, column);
275:
276: this.data[row][column] = object;
277: this.rows = Math.max(this.rows, row + 1);
278: this.columns = Math.max(this.columns, column + 1);
279: }
280:
281:
288: public boolean equals(final Object o)
289: {
290:
291: if (o == null)
292: {
293: return false;
294: }
295:
296: if (this == o)
297: {
298: return true;
299: }
300:
301: if ((o instanceof ObjectTable) == false)
302: {
303: return false;
304: }
305:
306: final ObjectTable ot = (ObjectTable) o;
307: if (getRowCount() != ot.getRowCount())
308: {
309: return false;
310: }
311:
312: if (getColumnCount() != ot.getColumnCount())
313: {
314: return false;
315: }
316:
317: for (int r = 0; r < getRowCount(); r++)
318: {
319: for (int c = 0; c < getColumnCount(); c++)
320: {
321: if (ObjectUtilities.equal(getObject(r, c),
322: ot.getObject(r, c)) == false)
323: {
324: return false;
325: }
326: }
327: }
328: return true;
329: }
330:
331:
336: public int hashCode()
337: {
338: int result;
339: result = this.rows;
340: result = 29 * result + this.columns;
341: return result;
342: }
343:
344:
350: private void writeObject(final ObjectOutputStream stream)
351: throws IOException
352: {
353: stream.defaultWriteObject();
354: final int rowCount = this.data.length;
355: stream.writeInt(rowCount);
356: for (int r = 0; r < rowCount; r++)
357: {
358: final Object[] column = this.data[r];
359: stream.writeBoolean(column != null);
360: if (column != null)
361: {
362: final int columnCount = column.length;
363: stream.writeInt(columnCount);
364: for (int c = 0; c < columnCount; c++)
365: {
366: writeSerializedData(stream, column[c]);
367: }
368: }
369: }
370: }
371:
372:
379: protected void writeSerializedData(final ObjectOutputStream stream,
380: final Object o)
381: throws IOException
382: {
383: stream.writeObject(o);
384: }
385:
386:
393: private void readObject(final ObjectInputStream stream)
394: throws IOException, ClassNotFoundException
395: {
396: stream.defaultReadObject();
397: final int rowCount = stream.readInt();
398: this.data = new Object[rowCount][];
399: for (int r = 0; r < rowCount; r++)
400: {
401: final boolean isNotNull = stream.readBoolean();
402: if (isNotNull)
403: {
404: final int columnCount = stream.readInt();
405: final Object[] column = new Object[columnCount];
406: this.data[r] = column;
407: for (int c = 0; c < columnCount; c++)
408: {
409: column[c] = readSerializedData(stream);
410: }
411: }
412: }
413: }
414:
415:
424: protected Object readSerializedData(final ObjectInputStream stream)
425: throws ClassNotFoundException, IOException
426: {
427: return stream.readObject();
428: }
429:
430:
433: public void clear()
434: {
435: this.rows = 0;
436: this.columns = 0;
437: for (int i = 0; i < this.data.length; i++)
438: {
439: if (this.data[i] != null)
440: {
441: Arrays.fill(this.data[i], null);
442: }
443: }
444: }
445:
446:
452: protected void copyColumn(final int oldColumn, final int newColumn)
453: {
454: for (int i = 0; i < getRowCount(); i++)
455: {
456: setObject(i, newColumn, getObject(i, oldColumn));
457: }
458: }
459:
460:
467: protected void copyRow(final int oldRow, final int newRow)
468: {
469: this.ensureCapacity(newRow, getColumnCount());
470: final Object[] oldRowStorage = this.data[oldRow];
471: if (oldRowStorage == null)
472: {
473: final Object[] newRowStorage = this.data[newRow];
474: if (newRowStorage != null)
475: {
476: Arrays.fill(newRowStorage, null);
477: }
478: }
479: else
480: {
481: this.data[newRow] = (Object[]) oldRowStorage.clone();
482: }
483: }
484:
485: protected void setData(final Object[][] data, final int colCount)
486: {
487: if (data == null) {
488: throw new NullPointerException();
489: }
490: if (colCount < 0) {
491: throw new IndexOutOfBoundsException();
492: }
493:
494: this.data = data;
495: this.rows = data.length;
496: this.columns = colCount;
497: }
498:
499: protected Object[][] getData()
500: {
501: return data;
502: }
503: }