From aee97922c4be64155f5fc1794d809bb73dbdd087 Mon Sep 17 00:00:00 2001 From: samskivert Date: Fri, 4 Sep 2009 17:25:45 +0000 Subject: [PATCH] Extract the proxied Connection creation code into a JDBCUtil method. git-svn-id: https://samskivert.googlecode.com/svn/trunk@2631 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../samskivert/jdbc/AutoCloseOperation.java | 25 +++------------ src/java/com/samskivert/jdbc/JDBCUtil.java | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/java/com/samskivert/jdbc/AutoCloseOperation.java b/src/java/com/samskivert/jdbc/AutoCloseOperation.java index 0d6f9d6d..22f1b75f 100644 --- a/src/java/com/samskivert/jdbc/AutoCloseOperation.java +++ b/src/java/com/samskivert/jdbc/AutoCloseOperation.java @@ -20,10 +20,6 @@ package com.samskivert.jdbc; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; @@ -52,24 +48,13 @@ public abstract class AutoCloseOperation /** * Invokes {@link #cleanInvoke} and then closes any statements opened by that call. */ - public final V invoke (final Connection conn, DatabaseLiaison liaison) + public final V invoke (Connection conn, DatabaseLiaison liaison) throws SQLException, PersistenceException { - // create a proxy to conn that collects any returned instances of Statement in stmts - final List stmts = new ArrayList(1); - Connection proxy = (Connection)Proxy.newProxyInstance( - Connection.class.getClassLoader(), PROXY_IFACES, new InvocationHandler() { - public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { - Object result = method.invoke(conn, args); - if (result instanceof Statement) { - stmts.add((Statement)result); - } - return result; - } - }); - + List stmts = new ArrayList(1); + conn = JDBCUtil.makeCollector(conn, stmts); try { - return cleanInvoke(proxy, liaison); + return cleanInvoke(conn, liaison); } finally { // if closing a statement throws an SQLException, we don't attempt to close the rest of // the statements -- an SQLException thrown on close is a problem with the underlying @@ -80,6 +65,4 @@ public abstract class AutoCloseOperation } } } - - protected static Class[] PROXY_IFACES = { Connection.class }; } diff --git a/src/java/com/samskivert/jdbc/JDBCUtil.java b/src/java/com/samskivert/jdbc/JDBCUtil.java index 5fd43da7..f3a24192 100644 --- a/src/java/com/samskivert/jdbc/JDBCUtil.java +++ b/src/java/com/samskivert/jdbc/JDBCUtil.java @@ -21,8 +21,15 @@ package com.samskivert.jdbc; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.List; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -31,6 +38,7 @@ import java.sql.Statement; import com.samskivert.io.PersistenceException; import com.samskivert.util.StringUtil; +import com.samskivert.util.Tuple; import static com.samskivert.Log.log; @@ -74,6 +82,27 @@ public class JDBCUtil } } + /** + * Wraps the given connection in a proxied instance that will add all statements returned by + * methods called on the proxy (such as {@link Collection#createStatement}) to the supplied + * list. Thus you can create the proxy, pass the proxy to code that creates and uses statements + * and then close any statements created by the code that operated on that Connection before + * returning it to a pool, for example. + */ + public static Connection makeCollector (final Connection conn, final List stmts) + { + return (Connection)Proxy.newProxyInstance( + Connection.class.getClassLoader(), PROXY_IFACES, new InvocationHandler() { + public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { + Object result = method.invoke(conn, args); + if (result instanceof Statement) { + stmts.add((Statement)result); + } + return result; + } + }); + } + /** * Calls stmt.executeUpdate() on the supplied statement, checking to see that it * returns the expected update count and throwing a persistence exception if it does not. @@ -621,4 +650,7 @@ public class JDBCUtil throw new SQLException("Table or Column not defined. [table=" + table + ", col=" + column + "]."); } + + /** Used by {@link #makeCollectingConnection}. */ + protected static Class[] PROXY_IFACES = { Connection.class }; }