package org.xorm.cache;
import javax.jdo.JDOUserException;
import org.xorm.datastore.Row;
import org.xorm.datastore.Table;
/**
* 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.
* @author Harry Evans
*/
public class RowCacheKeyFactory {
/**
* Take a row and return a key for it.
* @param value the Row to generate the key for, as an Object
* @return an opaque key for the Row.
* @exception ClassCastException if the object is not a Row.
*/
public Object getCacheKey(Object value) {
if(value == null) {
return null;
} else {
Row row = (Row)value;
return makeRowPrimaryKey(row.getTable(), row);
}
}
/**
* Take a table and a row, and make a cachable key for it.
* @param table the Table the row belongs to
* @param row the Row to generate the key for, as an Object
* @return an opaque key for the Row.
*/
public Object makeRowPrimaryKey(Table table, Row row) {
if (row == null || table == null) {
// Maybe throw an IllegalArgumentException?
return null;
}
else if (table.getPrimaryKey() == null) {
// Maybe throw a JDOUserException?
return null;
}
else if (!table.equals(row.getTable())) {
// Whoa...the row's table isn't the same as the table
// passed in. This should never happen but let's bitch
// if it does.
throw new JDOUserException("Table (" +
table.getName() +
") does not match Row's Table (" +
row.getTable().getName() + ")");
}
else {
return makeRowPrimaryKey(table, row.getPrimaryKeyValue());
}
}
/**
* Take a table and a row primary key, and make a cachable key for it.
* @param table the Table the row belongs to
* @param rowId the primary key of the Row object to be cached
* @return an opaque key for the Row.
*/
public Object makeRowPrimaryKey(Table table, Object rowId) {
if(table != null && rowId != null) {
return new RowPrimaryKey(table, rowId);
}
return null;
}
/**
* Class used to represent the primary key of a Row for caching purposes.
* The class guarantees equals and hashCode for multiple instances that are
* used for the same Row.
* @author Harry Evans
*/
private static class RowPrimaryKey {
private Object rowId;
private Table table;
private int hashValue;
public RowPrimaryKey(Table aTable, Object aRowId) {
table = aTable;
rowId = aRowId;
hashValue = table.hashCode() & rowId.hashCode();
}
public int hashCode() {
return hashValue;
}
public boolean equals(Object o) {
if(o == this) {
return true;
} else if(o != null && o instanceof RowPrimaryKey) {
RowPrimaryKey other = (RowPrimaryKey)o;
return (table == other.table && rowId.equals(other.rowId));
}
return false;
}
}
}