Starting down the path of converting everything to 1.5 and using Retroweaver to

make things work on the client. We're starting with parameterized types which
are backwards compatible with 1.4 anyway so all Retroweaver is doing to such
classes is changing the classfile format version number. We'll get more jiggy
later as we become more comfortable with the process.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@1809 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2006-04-10 02:39:30 +00:00
parent b79253cd76
commit cef9db2032
7 changed files with 189 additions and 276 deletions
+11 -2
View File
@@ -12,7 +12,6 @@
<!-- things you probably don't want to change --> <!-- things you probably don't want to change -->
<property name="src.dir" value="src/java"/> <property name="src.dir" value="src/java"/>
<property name="deploy.dir" value="dist"/> <property name="deploy.dir" value="dist"/>
<property name="dist.jar" value="${app.name}.jar"/>
<property name="javadoc.dir" value="${deploy.dir}/docs"/> <property name="javadoc.dir" value="${deploy.dir}/docs"/>
<property name="savedoc.dir" value="docs"/> <property name="savedoc.dir" value="docs"/>
@@ -184,6 +183,7 @@
<exclude name="com/samskivert/util/**" unless="build.util"/> <exclude name="com/samskivert/util/**" unless="build.util"/>
<exclude name="com/samskivert/velocity/**" unless="build.velocity"/> <exclude name="com/samskivert/velocity/**" unless="build.velocity"/>
<exclude name="com/samskivert/xml/**" unless="build.xml"/> <exclude name="com/samskivert/xml/**" unless="build.xml"/>
<compilerarg value="-Xlint:unchecked"/>
</javac> </javac>
</target> </target>
@@ -227,10 +227,19 @@
<!-- builds our distribution files (war and jar) --> <!-- builds our distribution files (war and jar) -->
<target name="dist" depends="prepare,compile"> <target name="dist" depends="prepare,compile">
<jar destfile="${deploy.dir}/${dist.jar}" <jar destfile="${deploy.dir}/${app.name}.jar"
basedir="${deploy.dir}/classes"/> basedir="${deploy.dir}/classes"/>
</target> </target>
<!-- converts our 1.5 code to a 1.4 compatible format -->
<target name="retro" depends="dist">
<taskdef name="weave" classpathref="classpath"
classname="com.rc.retroweaver.ant.RetroWeaverTask"/>
<mkdir dir="${deploy.dir}/retro"/>
<weave inputjar="${deploy.dir}/${app.name}.jar"
outputjar="${deploy.dir}/retro/${app.name}.jar"/>
</target>
<!-- generate a class hierarchy diagram --> <!-- generate a class hierarchy diagram -->
<target name="hiergen" depends="prepare,compile"> <target name="hiergen" depends="prepare,compile">
<taskdef name="viztool" classname="com.samskivert.viztool.DriverTask"/> <taskdef name="viztool" classname="com.samskivert.viztool.DriverTask"/>
+2 -2
View File
@@ -87,7 +87,7 @@ public class Repository
* as for it to automatically retry an operation if the connection * as for it to automatically retry an operation if the connection
* failed for some transient reason. * failed for some transient reason.
*/ */
public interface Operation public interface Operation<V>
{ {
/** /**
* Invokes code that performs one or more database operations, all * Invokes code that performs one or more database operations, all
@@ -110,7 +110,7 @@ public class Repository
* indicative of a basic JDBC failure. The transaction * indicative of a basic JDBC failure. The transaction
* <em>will</em> be rolled back in such cases, however. * <em>will</em> be rolled back in such cases, however.
*/ */
public Object invoke (Connection conn, DatabaseLiaison liaison) public V invoke (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException; throws SQLException, PersistenceException;
} }
@@ -91,7 +91,7 @@ public class SimpleRepository extends Repository
* *
* @return whatever value is returned by the invoked operation. * @return whatever value is returned by the invoked operation.
*/ */
protected Object execute (Operation op) protected <V> V execute (Operation<V> op)
throws PersistenceException throws PersistenceException
{ {
return execute(op, true); return execute(op, true);
@@ -111,12 +111,12 @@ public class SimpleRepository extends Repository
* *
* @return whatever value is returned by the invoked operation. * @return whatever value is returned by the invoked operation.
*/ */
protected Object execute (Operation op, boolean retryOnTransientFailure) protected <V> V execute (Operation<V> op, boolean retryOnTransientFailure)
throws PersistenceException throws PersistenceException
{ {
Connection conn = null; Connection conn = null;
DatabaseLiaison liaison = null; DatabaseLiaison liaison = null;
Object rv = null; V rv = null;
boolean supportsTransactions = false; boolean supportsTransactions = false;
boolean attemptedOperation = false; boolean attemptedOperation = false;
@@ -234,20 +234,19 @@ public class SimpleRepository extends Repository
protected int update (final String query) protected int update (final String query)
throws PersistenceException throws PersistenceException
{ {
Integer rv = (Integer)execute(new Operation() { return execute(new Operation<Integer>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Integer invoke (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException throws SQLException, PersistenceException
{ {
Statement stmt = null; Statement stmt = null;
try { try {
stmt = conn.createStatement(); stmt = conn.createStatement();
return new Integer(stmt.executeUpdate(query)); return stmt.executeUpdate(query);
} finally { } finally {
JDBCUtil.close(stmt); JDBCUtil.close(stmt);
} }
} }
}); });
return rv.intValue();
} }
/** /**
+71 -108
View File
@@ -21,7 +21,8 @@ import com.samskivert.Log;
* to database. Cursor also provides methods for updating/deleting current * to database. Cursor also provides methods for updating/deleting current
* record. * record.
*/ */
public class Cursor { public class Cursor<V>
{
/** /**
* A cursor is initially positioned before its first row; the * A cursor is initially positioned before its first row; the
* first call to next makes the first row the current row; the * first call to next makes the first row the current row; the
@@ -34,7 +35,7 @@ public class Cursor {
* @return object constructed from fetched record or null if there * @return object constructed from fetched record or null if there
* are no more rows * are no more rows
*/ */
public Object next() public V next ()
throws SQLException throws SQLException
{ {
// if we closed everything up after the last call to next(), // if we closed everything up after the last call to next(),
@@ -43,52 +44,49 @@ public class Cursor {
return null; return null;
} }
// try { do {
do { if (result == null) {
if (result == null) { if (table.isAbstract) {
if (table.isAbstract) { table = table.derived;
table = table.derived; continue;
continue; }
} if (qbeObject != null) {
if (qbeObject != null) { PreparedStatement qbeStmt;
PreparedStatement qbeStmt; synchronized(session.preparedStmtHash) {
synchronized(session.preparedStmtHash) { Object s = session.preparedStmtHash.get(query);
Object s = session.preparedStmtHash.get(query); if (s == null) {
if (s == null) { qbeStmt=
qbeStmt= session.connection.prepareStatement(query);
session.connection.prepareStatement(query); session.preparedStmtHash.put(query, qbeStmt);
session.preparedStmtHash.put(query, qbeStmt); } else {
} else { qbeStmt = (PreparedStatement)s;
qbeStmt = (PreparedStatement)s; }
} }
} synchronized(qbeStmt) {
synchronized(qbeStmt) { table.bindQueryVariables(
table.bindQueryVariables( qbeStmt, qbeObject, qbeMask);
qbeStmt, qbeObject, qbeMask); result = qbeStmt.executeQuery();
result = qbeStmt.executeQuery(); qbeStmt.clearParameters();
qbeStmt.clearParameters(); }
} } else {
} else { if (stmt == null) {
if (stmt == null) { stmt = session.connection.createStatement();
stmt = session.connection.createStatement(); }
} result = stmt.executeQuery(query);
result = stmt.executeQuery(query); }
} }
} if (result.next()) {
if (result.next()) { return currObject = table.load(result);
return currObject = table.load(result); }
} result.close();
result.close(); result = null;
result = null; currObject = null;
currObject = null; table = table.derived;
table = table.derived; } while (--nTables != 0);
} while (--nTables != 0);
if (stmt != null) { if (stmt != null) {
stmt.close(); stmt.close();
} }
// }
// catch (SQLException ex) { session.handleSQLException(ex); }
return null; return null;
} }
@@ -97,10 +95,10 @@ public class Cursor {
* were matched. Checks to ensure that no subsequent elements were matched * were matched. Checks to ensure that no subsequent elements were matched
* by the query, logs a warning if there were spurious additional matches. * by the query, logs a warning if there were spurious additional matches.
*/ */
public Object get() public V get ()
throws SQLException throws SQLException
{ {
Object result = next(); V result = next();
if (result != null) { if (result != null) {
int spurious = 0; int spurious = 0;
while (next() != null) { while (next() != null) {
@@ -129,16 +127,13 @@ public class Cursor {
* Not all database drivers support update operation with * Not all database drivers support update operation with
* cursor. This method will not work with such database drivers. * cursor. This method will not work with such database drivers.
*/ */
public void update() public void update ()
throws SQLException throws SQLException
{ {
if (currObject == null) { if (currObject == null) {
throw new NoCurrentObjectError(); throw new NoCurrentObjectError();
} }
// try { table.updateVariables(result, currObject);
table.updateVariables(result, currObject);
// }
// catch (SQLException ex) { session.handleSQLException(ex); }
} }
/** Delete current record pointed by cursor. This method can be called /** Delete current record pointed by cursor. This method can be called
@@ -154,16 +149,13 @@ public class Cursor {
* Not all database drivers support delete operation with cursor. * Not all database drivers support delete operation with cursor.
* This method will not work with such database drivers. * This method will not work with such database drivers.
*/ */
public void delete() public void delete ()
throws SQLException throws SQLException
{ {
if (currObject == null) { if (currObject == null) {
throw new NoCurrentObjectError(); throw new NoCurrentObjectError();
} }
// try { result.deleteRow();
result.deleteRow();
// }
// catch (SQLException ex) { session.handleSQLException(ex); }
} }
/** /**
@@ -181,40 +173,6 @@ public class Cursor {
nTables = 0; nTables = 0;
} }
/** Extracts no more than <I>maxElements</I> records from database and
* store them into array. It is possible to extract rest records
* by successive next() or toArray() calls. Selected objects should
* have now components of InputStream, Blob or Clob type, because
* their data will be not available after fetching next record.
*
* @param maxElements limitation for result array size (and also for number
* of fetched records)
* @return Array with objects constructed from fetched records.
*/
public Object[] toArray(int maxElements)
throws SQLException
{
Vector v = new Vector(maxElements < 100 ? maxElements : 100);
Object o;
while (--maxElements >= 0 && (o = next()) != null) {
v.addElement(o);
}
Object[] a = new Object[v.size()];
v.copyInto(a);
return a;
}
/** Store all objects returned by SELECT query into array of Object.
* Selected objects should have now components of InputStream, Blob or
* Clob type, because their data will be not available after fetching
* next record.
*
* @return Array with objects constructed from fetched records.
*/
public Object[] toArray()
throws SQLException
{ return toArray(Integer.MAX_VALUE); }
/** Extracts no more than <I>maxElements</I> records from database and /** Extracts no more than <I>maxElements</I> records from database and
* store them into array. It is possible to extract rest records * store them into array. It is possible to extract rest records
* by successive next() or toArray() calls. Selected objects should * by successive next() or toArray() calls. Selected objects should
@@ -225,15 +183,15 @@ public class Cursor {
* of fetched records) * of fetched records)
* @return List with objects constructed from fetched records. * @return List with objects constructed from fetched records.
*/ */
public List toArrayList(int maxElements) public ArrayList<V> toArrayList (int maxElements)
throws SQLException throws SQLException
{ {
ArrayList al = new ArrayList(maxElements < 100 ? maxElements : 100); ArrayList<V> al = new ArrayList(Math.min(maxElements, 100));
Object o; V o;
while (--maxElements >= 0 && (o = next()) != null) { while (--maxElements >= 0 && (o = next()) != null) {
al.add(o); al.add(o);
} }
return al; return al;
} }
/** Store all objects returned by SELECT query into a list of Object. /** Store all objects returned by SELECT query into a list of Object.
@@ -243,13 +201,17 @@ public class Cursor {
* *
* @return Array with objects constructed from fetched records. * @return Array with objects constructed from fetched records.
*/ */
public List toArrayList() public ArrayList<V> toArrayList()
throws SQLException throws SQLException
{ return toArrayList(Integer.MAX_VALUE); } {
return toArrayList(Integer.MAX_VALUE);
}
// Internals // Internals
protected Cursor(Table table, Session session, int nTables, String query) { protected Cursor (
Table<V> table, Session session, int nTables, String query)
{
if (session == null) { if (session == null) {
session = ((SessionThread)Thread.currentThread()).session; session = ((SessionThread)Thread.currentThread()).session;
} }
@@ -259,8 +221,9 @@ public class Cursor {
this.query = query; this.query = query;
} }
protected Cursor(Table table, Session session, int nTables, protected Cursor (Table<V> table, Session session, int nTables, V obj,
Object obj, FieldMask mask, boolean like) { FieldMask mask, boolean like)
{
if (session == null) { if (session == null) {
session = ((SessionThread)Thread.currentThread()).session; session = ((SessionThread)Thread.currentThread()).session;
} }
@@ -274,14 +237,14 @@ public class Cursor {
stmt = null; stmt = null;
} }
private Table table; private Table<V> table;
private Session session; private Session session;
private int nTables; private int nTables;
private ResultSet result; private ResultSet result;
private String query; private String query;
private Statement stmt; private Statement stmt;
private Object currObject; private V currObject;
private Object qbeObject; private V qbeObject;
private FieldMask qbeMask; private FieldMask qbeMask;
private boolean like; private boolean like;
} }
+76 -124
View File
@@ -21,11 +21,12 @@ import com.samskivert.util.StringUtil;
* SQL statements for extracting, updating and deleting records of the * SQL statements for extracting, updating and deleting records of the
* database table. * database table.
*/ */
public class Table { public class Table<T>
{
/** Constructor for table object. Make association between Java class /** Constructor for table object. Make association between Java class
* and database table. * and database table.
* *
* @param className name of Java class * @param clazz the class that represents a row entry.
* @param tableName name of database table mapped on this Java class * @param tableName name of database table mapped on this Java class
* @param s session, which should be opened before first access to the table * @param s session, which should be opened before first access to the table
* @param key table's primary key. This parameter is used in UPDATE/DELETE * @param key table's primary key. This parameter is used in UPDATE/DELETE
@@ -33,44 +34,44 @@ public class Table {
* @param mixedCaseConvert whether or not to convert mixed case field * @param mixedCaseConvert whether or not to convert mixed case field
* names into underscore separated uppercase column names. * names into underscore separated uppercase column names.
*/ */
public Table(String className, String tableName, Session s, String key, public Table(Class<T> clazz, String tableName, Session s, String key,
boolean mixedCaseConvert) { boolean mixedCaseConvert) {
String[] keys = {key}; String[] keys = {key};
init(className, tableName, s, keys, mixedCaseConvert); init(clazz, tableName, s, keys, mixedCaseConvert);
} }
/** Constructor for table object. Make association between Java class /** Constructor for table object. Make association between Java class
* and database table. * and database table.
* *
* @param className name of Java class * @param clazz the class that represents a row entry.
* @param tableName name of database table mapped on this Java class * @param tableName name of database table mapped on this Java class
* @param key table's primary key. This parameter is used in UPDATE/DELETE * @param key table's primary key. This parameter is used in UPDATE/DELETE
* operations to locate record in the table. * operations to locate record in the table.
* @param s session, which should be opened before first access to the table * @param s session, which should be opened before first access to the table
*/ */
public Table(String className, String tableName, Session s, String key) { public Table(Class<T> clazz, String tableName, Session s, String key) {
String[] keys = {key}; String[] keys = {key};
init(className, tableName, s, keys, false); init(clazz, tableName, s, keys, false);
} }
/** Constructor for table object. Make association between Java class /** Constructor for table object. Make association between Java class
* and database table. * and database table.
* *
* @param className name of Java class * @param clazz the class that represents a row entry.
* @param tableName name of database table mapped on this Java class * @param tableName name of database table mapped on this Java class
* @param keys table primary keys. This parameter is used in UPDATE/DELETE * @param keys table primary keys. This parameter is used in UPDATE/DELETE
* operations to locate record in the table. * operations to locate record in the table.
* @param s session, which should be opened before first access to the table * @param s session, which should be opened before first access to the table
*/ */
public Table(String className, String tableName, Session s, String[] keys) public Table(Class<T> clazz, String tableName, Session s, String[] keys)
{ {
init(className, tableName, s, keys, false); init(clazz, tableName, s, keys, false);
} }
/** Constructor for table object. Make association between Java class /** Constructor for table object. Make association between Java class
* and database table. * and database table.
* *
* @param className name of Java class * @param clazz the class that represents a row entry.
* @param tableName name of database table mapped on this Java class * @param tableName name of database table mapped on this Java class
* @param keys table primary keys. This parameter is used in UPDATE/DELETE * @param keys table primary keys. This parameter is used in UPDATE/DELETE
* operations to locate record in the table. * operations to locate record in the table.
@@ -78,57 +79,9 @@ public class Table {
* @param mixedCaseConvert whether or not to convert mixed case field * @param mixedCaseConvert whether or not to convert mixed case field
* names into underscore separated uppercase column names. * names into underscore separated uppercase column names.
*/ */
public Table(String className, String tableName, Session s, String[] keys, public Table(Class<T> clazz, String tableName, Session s, String[] keys,
boolean mixedCaseConvert) { boolean mixedCaseConvert) {
init(className, tableName, s, keys, mixedCaseConvert); init(clazz, tableName, s, keys, mixedCaseConvert);
}
/** Constructor for table object. Make association between Java class
* and database table. Name of Java class should be the same as name of
* the database table
*
* @param className name of Java class, which should be (without
* package prefix) be the same as the name of database table.
* @param keys table primary keys. This parameter is used in UPDATE/DELETE
* operations to locate record in the table.
* @param s session, which should be opened before first access to the table
*/
public Table(String className, Session s, String[] keys) {
init(className, className.substring(className.lastIndexOf('.')+1),
s, keys, false);
}
/** Constructor for table object. Make association between Java class
* and database table. Name of Java class should be the same as name of
* the database table
*
* @param className name of Java class, which should be (without
* package prefix) be the same as the name of database table.
* @param key table primary key. This parameter is used in UPDATE/DELETE
* operations to locate record in the table.
* @param s session, which should be opened before first access to the table
*/
public Table(String className, Session s, String key) {
String[] keys = {key};
init(className, className.substring(className.lastIndexOf('.')+1),
s, keys, false);
}
/** Constructor of table without explicit key specification.
* Specification of key is necessary for update/remove operations.
* If key is not specified, it is inherited from base table (if any).
*/
public Table(String className, Session s) {
init(className, className.substring(className.lastIndexOf('.')+1),
s, null, false);
}
/** Constructor of table with "key" and "session" parameters inherited
* from base table.
*/
public Table(String className) {
init(className, className.substring(className.lastIndexOf('.')+1),
null, null, false);
} }
/** Select records from database table according to search condition /** Select records from database table according to search condition
@@ -136,10 +89,10 @@ public class Table {
* @param condition valid SQL condition expression started with WHERE * @param condition valid SQL condition expression started with WHERE
* or empty string if all records should be fetched. * or empty string if all records should be fetched.
*/ */
public final Cursor select(String condition) { public final Cursor<T> select(String condition) {
String query = "select " + listOfFields + " from " + name + String query = "select " + listOfFields + " from " + name +
" " + condition; " " + condition;
return new Cursor(this, session, 1, query); return new Cursor<T>(this, session, 1, query);
} }
/** Select records from database table according to search condition /** Select records from database table according to search condition
@@ -150,10 +103,10 @@ public class Table {
* include in the SELECT clause. * include in the SELECT clause.
* @param condition valid SQL condition expression started with WHERE. * @param condition valid SQL condition expression started with WHERE.
*/ */
public final Cursor select(String tables, String condition) { public final Cursor<T> select(String tables, String condition) {
String query = "select " + qualifiedListOfFields + String query = "select " + qualifiedListOfFields +
" from " + name + "," + tables + " " + condition; " from " + name + "," + tables + " " + condition;
return new Cursor(this, session, 1, query); return new Cursor<T>(this, session, 1, query);
} }
/** Select records from database table according to search condition /** Select records from database table according to search condition
@@ -167,18 +120,18 @@ public class Table {
* include in the SELECT clause. * include in the SELECT clause.
* @param condition valid SQL condition expression started with WHERE. * @param condition valid SQL condition expression started with WHERE.
*/ */
public final Cursor join(String tables, String condition) { public final Cursor<T> join(String tables, String condition) {
String query = "select " + listOfFields + String query = "select " + listOfFields +
" from " + name + "," + tables + " " + condition; " from " + name + "," + tables + " " + condition;
return new Cursor(this, session, 1, query); return new Cursor<T>(this, session, 1, query);
} }
/** Like {@link #join} but does a straight join with the specified /** Like {@link #join} but does a straight join with the specified
* table. */ * table. */
public final Cursor straightJoin(String table, String condition) { public final Cursor<T> straightJoin(String table, String condition) {
String query = "select " + listOfFields + String query = "select " + listOfFields +
" from " + name + " straight_join " + table + " " + condition; " from " + name + " straight_join " + table + " " + condition;
return new Cursor(this, session, 1, query); return new Cursor<T>(this, session, 1, query);
} }
/** Select records from database table according to search condition /** Select records from database table according to search condition
@@ -187,10 +140,10 @@ public class Table {
* or empty string if all records should be fetched. * or empty string if all records should be fetched.
* @param session user database session * @param session user database session
*/ */
public final Cursor select(String condition, Session session) { public final Cursor<T> select(String condition, Session session) {
String query = "select " + listOfFields + " from " + name + String query = "select " + listOfFields + " from " + name +
" " + condition; " " + condition;
return new Cursor(this, session, 1, query); return new Cursor<T>(this, session, 1, query);
} }
/** Select records from specified and derived database tables /** Select records from specified and derived database tables
@@ -198,8 +151,8 @@ public class Table {
* @param condition valid SQL condition expression started with WHERE * @param condition valid SQL condition expression started with WHERE
* or empty string if all records should be fetched. * or empty string if all records should be fetched.
*/ */
public final Cursor selectAll(String condition) { public final Cursor<T> selectAll(String condition) {
return new Cursor(this, session, nDerived+1, condition); return new Cursor<T>(this, session, nDerived+1, condition);
} }
/** Select records from specified and derived database tables /** Select records from specified and derived database tables
@@ -208,8 +161,8 @@ public class Table {
* or empty string if all records should be fetched. * or empty string if all records should be fetched.
* @param session user database session * @param session user database session
*/ */
public final Cursor selectAll(String condition, Session session) { public final Cursor<T> selectAll(String condition, Session session) {
return new Cursor(this, session, nDerived+1, condition); return new Cursor<T>(this, session, nDerived+1, condition);
} }
/** Select records from database table using <I>obj</I> object as /** Select records from database table using <I>obj</I> object as
@@ -218,8 +171,8 @@ public class Table {
* @param obj example object for search: selected objects should match * @param obj example object for search: selected objects should match
* all non-null fields. * all non-null fields.
*/ */
public final Cursor queryByExample(Object obj) { public final Cursor<T> queryByExample(T obj) {
return new Cursor(this, session, 1, obj, null, false); return new Cursor<T>(this, session, 1, obj, null, false);
} }
/** Select records from database table using <I>obj</I> object as /** Select records from database table using <I>obj</I> object as
@@ -229,10 +182,10 @@ public class Table {
* @param mask field mask indicating which fields in the example * @param mask field mask indicating which fields in the example
* object should be used when building the query. * object should be used when building the query.
*/ */
public final Cursor queryByExample(Object obj, FieldMask mask) { public final Cursor<T> queryByExample(T obj, FieldMask mask) {
return new Cursor(this, session, 1, obj, mask, false); return new Cursor<T>(this, session, 1, obj, mask, false);
} }
/** Select records from database table using <I>obj</I> object as /** Select records from database table using <I>obj</I> object as
* template for selection. All non-builtin fields of this object, * template for selection. All non-builtin fields of this object,
* which are not null, are compared with correspondent table values. * which are not null, are compared with correspondent table values.
@@ -241,7 +194,7 @@ public class Table {
* objects should match all non-null fields of specified object. * objects should match all non-null fields of specified object.
* @param session user database session. * @param session user database session.
*/ */
public final Cursor queryByExample(Object obj, Session session) { public final Cursor<T> queryByExample(T obj, Session session) {
return queryByExample(obj, session, null); return queryByExample(obj, session, null);
} }
@@ -253,9 +206,9 @@ public class Table {
* @param mask field mask indicating which fields in the example * @param mask field mask indicating which fields in the example
* object should be used when building the query. * object should be used when building the query.
*/ */
public final Cursor queryByExample(Object obj, Session session, public final Cursor<T> queryByExample(
FieldMask mask) { T obj, Session session, FieldMask mask) {
return new Cursor(this, session, 1, obj, mask, false); return new Cursor<T>(this, session, 1, obj, mask, false);
} }
/** /**
@@ -263,8 +216,8 @@ public class Table {
* matched using 'like' instead of equals, which allows you to send % * matched using 'like' instead of equals, which allows you to send %
* in to do matching. * in to do matching.
*/ */
public final Cursor queryByLikeExample(Object obj) { public final Cursor<T> queryByLikeExample(T obj) {
return new Cursor(this, session, 1, obj, null, true); return new Cursor<T>(this, session, 1, obj, null, true);
} }
/** /**
@@ -272,8 +225,8 @@ public class Table {
* matched using 'like' instead of equals, which allows you to send % * matched using 'like' instead of equals, which allows you to send %
* in to do matching. * in to do matching.
*/ */
public final Cursor queryByLikeExample(Object obj, FieldMask mask) { public final Cursor<T> queryByLikeExample(T obj, FieldMask mask) {
return new Cursor(this, session, 1, obj, mask, true); return new Cursor<T>(this, session, 1, obj, mask, true);
} }
/** /**
@@ -281,7 +234,7 @@ public class Table {
* matched using 'like' instead of equals, which allows you to send % * matched using 'like' instead of equals, which allows you to send %
* in to do matching. * in to do matching.
*/ */
public final Cursor queryByLikeExample(Object obj, Session session) { public final Cursor<T> queryByLikeExample(T obj, Session session) {
return queryByLikeExample(obj, session, null); return queryByLikeExample(obj, session, null);
} }
@@ -290,11 +243,11 @@ public class Table {
* matched using 'like' instead of equals, which allows you to send % * matched using 'like' instead of equals, which allows you to send %
* in to do matching. * in to do matching.
*/ */
public final Cursor queryByLikeExample(Object obj, Session session, public final Cursor<T> queryByLikeExample(
FieldMask mask) { T obj, Session session, FieldMask mask) {
return new Cursor(this, session, 1, obj, mask, true); return new Cursor(this, session, 1, obj, mask, true);
} }
/** Select records from specified and derived database tables using /** Select records from specified and derived database tables using
* <I>obj</I> object as template for selection. All non-builtin * <I>obj</I> object as template for selection. All non-builtin
* fields of this object, which are not null, are compared with * fields of this object, which are not null, are compared with
@@ -303,7 +256,7 @@ public class Table {
* @param obj object for construction search condition: selected * @param obj object for construction search condition: selected
* objects should match all non-null fields of specified object. * objects should match all non-null fields of specified object.
*/ */
public final Cursor queryAllByExample(Object obj) { public final Cursor queryAllByExample(T obj) {
return new Cursor(this, session, nDerived+1, obj, null, false); return new Cursor(this, session, nDerived+1, obj, null, false);
} }
@@ -316,7 +269,7 @@ public class Table {
* should match all non-null fields of specified object. * should match all non-null fields of specified object.
* @param session user database session * @param session user database session
*/ */
public final Cursor queryAllByExample(Object obj, Session session) { public final Cursor queryAllByExample(T obj, Session session) {
return new Cursor(this, session, nDerived+1, obj, null, false); return new Cursor(this, session, nDerived+1, obj, null, false);
} }
@@ -325,7 +278,7 @@ public class Table {
* *
* @param obj object specifing values of inserted record fields * @param obj object specifing values of inserted record fields
*/ */
public void insert(Object obj) public void insert(T obj)
throws SQLException throws SQLException
{ {
insert(obj, session); insert(obj, session);
@@ -338,7 +291,7 @@ public class Table {
* @param obj object specifing values of inserted record fields * @param obj object specifing values of inserted record fields
* @param session user database session * @param session user database session
*/ */
public synchronized void insert(Object obj, Session session) public synchronized void insert(T obj, Session session)
throws SQLException throws SQLException
{ {
if (session == null) { if (session == null) {
@@ -367,7 +320,7 @@ public class Table {
* @param objects array with objects specifing values of inserted record * @param objects array with objects specifing values of inserted record
* fields * fields
*/ */
public void insert(Object[] objects) public void insert(T[] objects)
throws SQLException throws SQLException
{ {
insert(objects, session); insert(objects, session);
@@ -380,7 +333,7 @@ public class Table {
* fields * fields
* @param session user database session * @param session user database session
*/ */
public synchronized void insert(Object[] objects, Session session) public synchronized void insert(T[] objects, Session session)
throws SQLException throws SQLException
{ {
if (session == null) { if (session == null) {
@@ -408,7 +361,7 @@ public class Table {
/** Returns a field mask that can be configured and used to update /** Returns a field mask that can be configured and used to update
* subsets of entire objects via calls to {@link * subsets of entire objects via calls to {@link
* #update(Object,FieldMask)}. * #update(T,FieldMask)}.
*/ */
public FieldMask getFieldMask () public FieldMask getFieldMask ()
{ {
@@ -424,7 +377,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public int update(Object obj) public int update(T obj)
throws SQLException throws SQLException
{ {
return update(obj, null, session); return update(obj, null, session);
@@ -443,7 +396,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public int update(Object obj, FieldMask mask) public int update(T obj, FieldMask mask)
throws SQLException throws SQLException
{ {
return update(obj, mask, session); return update(obj, mask, session);
@@ -459,7 +412,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public synchronized int update(Object obj, Session session) public synchronized int update(T obj, Session session)
throws SQLException throws SQLException
{ {
return update(obj, null, session); return update(obj, null, session);
@@ -479,7 +432,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public synchronized int update(Object obj, FieldMask mask, Session session) public synchronized int update(T obj, FieldMask mask, Session session)
throws SQLException throws SQLException
{ {
if (primaryKeys == null) { if (primaryKeys == null) {
@@ -530,7 +483,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public int update(Object[] objects) public int update(T[] objects)
throws SQLException throws SQLException
{ {
return update(objects, session); return update(objects, session);
@@ -546,7 +499,7 @@ public class Table {
* *
* @return number of objects actually updated * @return number of objects actually updated
*/ */
public synchronized int update(Object[] objects, Session session) public synchronized int update(T[] objects, Session session)
throws SQLException throws SQLException
{ {
if (primaryKeys == null) { if (primaryKeys == null) {
@@ -587,7 +540,7 @@ public class Table {
* *
* @return number of objects actually deleted * @return number of objects actually deleted
*/ */
public int delete(Object obj) public int delete(T obj)
throws SQLException throws SQLException
{ {
return delete(obj, session); return delete(obj, session);
@@ -598,7 +551,7 @@ public class Table {
* @param obj object containing value of primary key. * @param obj object containing value of primary key.
* @param session user database session * @param session user database session
*/ */
public synchronized int delete(Object obj, Session session) public synchronized int delete(T obj, Session session)
throws SQLException throws SQLException
{ {
if (primaryKeys == null) { if (primaryKeys == null) {
@@ -633,7 +586,7 @@ public class Table {
* *
* @return number of objects actually deleted * @return number of objects actually deleted
*/ */
public int delete(Object[] objects) public int delete(T[] objects)
throws SQLException throws SQLException
{ {
return delete(objects, session); return delete(objects, session);
@@ -645,7 +598,7 @@ public class Table {
* *
* @return number of objects actually deleted * @return number of objects actually deleted
*/ */
public synchronized int delete(Object[] objects, Session session) public synchronized int delete(T[] objects, Session session)
throws SQLException throws SQLException
{ {
if (primaryKeys == null) { if (primaryKeys == null) {
@@ -734,7 +687,7 @@ public class Table {
private PreparedStatement insertStmt; private PreparedStatement insertStmt;
private static Table allTables; private static Table allTables;
private Constructor constructor; private Constructor<T> constructor;
private static Method setBypass; private static Method setBypass;
private static final Object[] bypassFlag = { new Boolean(true) }; private static final Object[] bypassFlag = { new Boolean(true) };
@@ -750,14 +703,12 @@ public class Table {
} }
private final void init(String className, String tableName, Session s, private final void init(Class<T> clazz, String tableName, Session s,
String[] keys, boolean mixedCaseConvert) String[] keys, boolean mixedCaseConvert)
{ {
name = tableName; name = tableName;
this.mixedCaseConvert = mixedCaseConvert; this.mixedCaseConvert = mixedCaseConvert;
try { cls = clazz;
cls = Class.forName(className);
} catch(ClassNotFoundException ex) {throw new NoClassDefFoundError();}
isAbstract = tableName == null; isAbstract = tableName == null;
session = s; session = s;
primaryKeys = keys; primaryKeys = keys;
@@ -998,8 +949,9 @@ public class Table {
return sql.toString(); return sql.toString();
} }
protected final Object load(ResultSet result) throws SQLException { protected final T load (ResultSet result) throws SQLException
Object obj; {
T obj;
try { try {
obj = constructor.newInstance(constructorArgs); obj = constructor.newInstance(constructorArgs);
} }
@@ -1012,8 +964,8 @@ public class Table {
return obj; return obj;
} }
private final int load(Object obj, int i, int end, int column, private final int load (
ResultSet result) Object obj, int i, int end, int column, ResultSet result)
throws SQLException throws SQLException
{ {
try { try {
@@ -1039,7 +991,7 @@ public class Table {
} }
protected final int bindUpdateVariables(PreparedStatement pstmt, protected final int bindUpdateVariables(PreparedStatement pstmt,
Object obj, T obj,
FieldMask mask) FieldMask mask)
throws SQLException throws SQLException
{ {
@@ -1047,14 +999,14 @@ public class Table {
} }
protected final void bindQueryVariables(PreparedStatement pstmt, protected final void bindQueryVariables(PreparedStatement pstmt,
Object obj, T obj,
FieldMask mask) FieldMask mask)
throws SQLException throws SQLException
{ {
bindQueryVariables(pstmt, obj, 0, nFields, 0, mask); bindQueryVariables(pstmt, obj, 0, nFields, 0, mask);
} }
protected final void updateVariables(ResultSet result, Object obj) protected final void updateVariables(ResultSet result, T obj)
throws SQLException throws SQLException
{ {
updateVariables(result, obj, 0, nFields, 0); updateVariables(result, obj, 0, nFields, 0);
@@ -1071,7 +1023,7 @@ public class Table {
return sql.toString(); return sql.toString();
} }
protected final String buildQueryList(Object qbe, FieldMask mask, boolean like) protected final String buildQueryList(T qbe, FieldMask mask, boolean like)
{ {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buildQueryList(buf, qbe, 0, nFields, mask, like); buildQueryList(buf, qbe, 0, nFields, mask, like);
@@ -1174,8 +1126,8 @@ public class Table {
return column; return column;
} }
private final void buildQueryList(StringBuffer buf, Object qbe, private final void buildQueryList(StringBuffer buf, Object qbe, int i,
int i, int end, FieldMask mask, boolean like) int end, FieldMask mask, boolean like)
{ {
try { try {
while (i < end) { while (i < end) {
@@ -74,22 +74,11 @@ public class UserRepository extends JORARepository
super(provider, USER_REPOSITORY_IDENT); super(provider, USER_REPOSITORY_IDENT);
} }
/**
* Derived classes that extend the user record with their own
* additional information will want to override this method and return
* their desired {@link User} derivation.
*/
protected Class getUserClass ()
{
return User.class;
}
// documentation inherited // documentation inherited
protected void createTables (Session session) protected void createTables (Session session)
{ {
// create our table object // create our table object
_utable = new Table( _utable = new Table<User>(User.class, "users", session, "userId");
getUserClass().getName(), "users", session, "userId");
} }
/** /**
@@ -155,8 +144,8 @@ public class UserRepository extends JORARepository
public User loadUserBySession (final String sessionKey) public User loadUserBySession (final String sessionKey)
throws PersistenceException throws PersistenceException
{ {
return (User)execute(new Operation () { return execute(new Operation<User>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public User invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
String query = "where authcode = '" + sessionKey + String query = "where authcode = '" + sessionKey +
@@ -193,8 +182,8 @@ public class UserRepository extends JORARepository
final String ids = genIdString(userIds); final String ids = genIdString(userIds);
return (HashIntMap)execute(new Operation () { return execute(new Operation<HashIntMap>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public HashIntMap invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
// look up the users // look up the users
@@ -220,13 +209,14 @@ public class UserRepository extends JORARepository
* @return the user with the specified user id or null if no user with * @return the user with the specified user id or null if no user with
* that id exists. * that id exists.
*/ */
public ArrayList lookupUsersByEmail (String email) public ArrayList<User> lookupUsersByEmail (String email)
throws PersistenceException throws PersistenceException
{ {
final String where = "where email = " + final String where = "where email = " +
JDBCUtil.escape(email); JDBCUtil.escape(email);
return (ArrayList) execute(new Operation() { return execute(new Operation<ArrayList<User>>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public ArrayList<User> invoke (Connection conn,
DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
return _utable.select(where).toArrayList(); return _utable.select(where).toArrayList();
@@ -242,14 +232,14 @@ public class UserRepository extends JORARepository
* @return the users matching the specified query or an empty list if there * @return the users matching the specified query or an empty list if there
* are no matches. * are no matches.
*/ */
public ArrayList lookupUsersWhere (final String where) public ArrayList<User> lookupUsersWhere (final String where)
throws PersistenceException throws PersistenceException
{ {
return (ArrayList) execute(new Operation() { return execute(new Operation<ArrayList<User>>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public ArrayList invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
ArrayList users = (ArrayList) ArrayList<User> users = (ArrayList<User>)
_utable.select("where " + where).toArrayList(); _utable.select("where " + where).toArrayList();
for (Iterator iter = users.iterator(); iter.hasNext(); ) { for (Iterator iter = users.iterator(); iter.hasNext(); ) {
// configure the user record with its field mask // configure the user record with its field mask
@@ -277,7 +267,7 @@ public class UserRepository extends JORARepository
return false; return false;
} }
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -312,7 +302,7 @@ public class UserRepository extends JORARepository
return; return;
} }
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -367,7 +357,7 @@ public class UserRepository extends JORARepository
final Date expires = new Date(cal.getTime().getTime()); final Date expires = new Date(cal.getTime().getTime());
// insert the session into the database // insert the session into the database
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -390,7 +380,7 @@ public class UserRepository extends JORARepository
public void pruneSessions () public void pruneSessions ()
throws PersistenceException throws PersistenceException
{ {
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -436,7 +426,7 @@ public class UserRepository extends JORARepository
final ArrayList names = new ArrayList(); final ArrayList names = new ArrayList();
// do the query // do the query
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -486,7 +476,7 @@ public class UserRepository extends JORARepository
protected int insertUser (final User user) protected int insertUser (final User user)
throws UserExistsException, PersistenceException throws UserExistsException, PersistenceException
{ {
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -517,8 +507,8 @@ public class UserRepository extends JORARepository
protected User loadUserWhere (final String whereClause) protected User loadUserWhere (final String whereClause)
throws PersistenceException throws PersistenceException
{ {
return (User)execute(new Operation () { return execute(new Operation<User>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public User invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
// look up the user // look up the user
@@ -551,7 +541,7 @@ public class UserRepository extends JORARepository
final HashIntMap map = new HashIntMap(); final HashIntMap map = new HashIntMap();
// do the query // do the query
execute(new Operation () { execute(new Operation<Object>() {
public Object invoke (Connection conn, DatabaseLiaison liaison) public Object invoke (Connection conn, DatabaseLiaison liaison)
throws PersistenceException, SQLException throws PersistenceException, SQLException
{ {
@@ -451,7 +451,7 @@ public class DispatcherServlet extends VelocityServlet
path = siteId + ":" + path; path = siteId + ":" + path;
} }
// Log.info("Loading template [path=" + path + "]."); // Log.info("Loading template [path=" + path + "].");
return RuntimeSingleton.getRuntimeServices().getTemplate(path); return RuntimeSingleton.getTemplate(path);
} }
/** /**