01: package org.xorm.cache;
02:
03: import javax.jdo.JDOUserException;
04: import org.xorm.datastore.Row;
05: import org.xorm.datastore.Table;
06:
07: /**
08: * Utility class used by the LRUCache to generate keys for the Rows it must store. This class produces a key suitable for using in a hash. This class is used, due to the anticiaption of other types of objects eventually being cached in the LRUCache.
09: * @author Harry Evans
10: */
11: public class RowCacheKeyFactory {
12: /**
13: * Take a row and return a key for it.
14: * @param value the Row to generate the key for, as an Object
15: * @return an opaque key for the Row.
16: * @exception ClassCastException if the object is not a Row.
17: */
18: public Object getCacheKey(Object value) {
19: if (value == null) {
20: return null;
21: } else {
22: Row row = (Row) value;
23: return makeRowPrimaryKey(row.getTable(), row);
24: }
25: }
26:
27: /**
28: * Take a table and a row, and make a cachable key for it.
29: * @param table the Table the row belongs to
30: * @param row the Row to generate the key for, as an Object
31: * @return an opaque key for the Row.
32: */
33: public Object makeRowPrimaryKey(Table table, Row row) {
34: if (row == null || table == null) {
35: // Maybe throw an IllegalArgumentException?
36: return null;
37: } else if (table.getPrimaryKey() == null) {
38: // Maybe throw a JDOUserException?
39: return null;
40: } else if (!table.equals(row.getTable())) {
41: // Whoa...the row's table isn't the same as the table
42: // passed in. This should never happen but let's bitch
43: // if it does.
44: throw new JDOUserException("Table (" + table.getName()
45: + ") does not match Row's Table ("
46: + row.getTable().getName() + ")");
47: } else {
48: return makeRowPrimaryKey(table, row.getPrimaryKeyValue());
49: }
50: }
51:
52: /**
53: * Take a table and a row primary key, and make a cachable key for it.
54: * @param table the Table the row belongs to
55: * @param rowId the primary key of the Row object to be cached
56: * @return an opaque key for the Row.
57: */
58: public Object makeRowPrimaryKey(Table table, Object rowId) {
59: if (table != null && rowId != null) {
60: return new RowPrimaryKey(table, rowId);
61: }
62: return null;
63: }
64:
65: /**
66: * Class used to represent the primary key of a Row for caching purposes.
67: * The class guarantees equals and hashCode for multiple instances that are
68: * used for the same Row.
69: * @author Harry Evans
70: */
71: private static class RowPrimaryKey {
72: private Object rowId;
73: private Table table;
74: private int hashValue;
75:
76: public RowPrimaryKey(Table aTable, Object aRowId) {
77: table = aTable;
78: rowId = aRowId;
79: hashValue = table.hashCode() & rowId.hashCode();
80: }
81:
82: public int hashCode() {
83: return hashValue;
84: }
85:
86: public boolean equals(Object o) {
87: if (o == this ) {
88: return true;
89: } else if (o != null && o instanceof RowPrimaryKey) {
90: RowPrimaryKey other = (RowPrimaryKey) o;
91: return (table == other.table && rowId
92: .equals(other.rowId));
93: }
94: return false;
95: }
96: }
97: }
|