You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by pr...@apache.org on 2003/04/08 20:34:34 UTC
cvs commit: avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource ProxiedJdbcConnection.java AbstractJdbcConnection.java JdbcConnectionFactory.java
proyal 2003/04/08 11:34:34
Modified: datasource/src/java/org/apache/avalon/excalibur/datasource
AbstractJdbcConnection.java
JdbcConnectionFactory.java
Added: datasource/src/java/org/apache/avalon/excalibur/datasource
ProxiedJdbcConnection.java
Log:
Fix proxy-based datasource
* AbstractJdbcConnection cannot return 'this' to the pool, as that
is not its proxied self.
* Added ProxiedJdbcConnection interface to allow invocation handler
to get proxied version of self as well as to allow retrieval
of underlying connection
* Disable lastUsed-based expiration of connections, since it was
borked anyways
* Implement equals() on AbstractJdbcConnection so that put()'s to the
pool work correctly.
* Remove unused parameter from JdbcConnectionFactory.init()
* Dispose any Disposable in JdbcConnectionFactory
* The InvocationHandler created in JdbcConnectionFactory must implement
ProxiedJdbcConnection so that it can receive a handle to its proxied
self.
Revision Changes Path
1.27 +76 -43 avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource/AbstractJdbcConnection.java
Index: AbstractJdbcConnection.java
===================================================================
RCS file: /home/cvs/avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource/AbstractJdbcConnection.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- AbstractJdbcConnection.java 6 Mar 2003 19:47:47 -0000 1.26
+++ AbstractJdbcConnection.java 8 Apr 2003 18:34:33 -0000 1.27
@@ -3,34 +3,34 @@
============================================================================
The Apache Software License, Version 1.1
============================================================================
-
+
Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
-
+
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
-
+
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
-
+
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
-
+
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
-
- 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
- must not be used to endorse or promote products derived from this software
- without prior written permission. For written permission, please contact
+
+ 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
+ must not be used to endorse or promote products derived from this software
+ without prior written permission. For written permission, please contact
apache@apache.org.
-
+
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
-
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
@@ -41,16 +41,17 @@
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+
This software consists of voluntary contributions made by many individuals
- on behalf of the Apache Software Foundation. For more information on the
+ on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
-
+
*/
package org.apache.avalon.excalibur.datasource;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationHandler;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -63,6 +64,7 @@
import java.util.Map;
import org.apache.avalon.excalibur.pool.Pool;
+import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
@@ -72,30 +74,33 @@
* object.
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
+ * @author <a href="mailto:proyal@apache.org">Peter Royal</a>
* @version CVS $Revision$ $Date$
* @since 4.1
*/
public class AbstractJdbcConnection
- extends AbstractLogEnabled
- implements PoolSettable, Disposable, InvocationHandler
+ extends AbstractLogEnabled
+ implements PoolSettable, Disposable, ProxiedJdbcConnection
{
protected Connection m_connection;
+ private Object m_proxy;
protected Pool m_pool;
protected PreparedStatement m_testStatement;
protected SQLException m_testException;
protected long m_lastUsed = System.currentTimeMillis();
private static final Map m_methods;
-
- static {
+
+ static
+ {
m_methods = new HashMap();
Method[] methods = AbstractJdbcConnection.class.getDeclaredMethods();
-
- for ( int i = 0; i < methods.length; i++ )
+
+ for( int i = 0; i < methods.length; i++ )
{
- m_methods.put(methods[i].getName(), methods[i]);
+ m_methods.put( methods[i].getName(), methods[i] );
}
}
-
+
/**
* Contains Statements created on the original jdbc connection
* between a {@link JdbcDataSource#getConnection} and {@link
@@ -189,8 +194,18 @@
}
}
+ public void setProxiedConnection( Object proxy )
+ {
+ m_proxy = proxy;
+ }
+
+ public Connection getConnection()
+ {
+ return m_connection;
+ }
+
public boolean isClosed()
- throws SQLException
+ throws SQLException
{
if( m_connection.isClosed() )
{
@@ -198,11 +213,14 @@
}
long age = System.currentTimeMillis() - m_lastUsed;
- if( age > 1000 * 60 * 60 ) // over an hour?
- {
- this.dispose();
- return true;
- }
+// Commenting out the hour check since it was to check an hour since last use, but since the
+// last-use time is not being updated anywhere, it has turned into "all connections expire after
+// an hour"
+// if( age > 1000 * 60 * 60 ) // over an hour?
+// {
+// this.dispose();
+// return true;
+// }
if( m_testStatement != null && age > ( 5 * 1000 ) ) // over 5 seconds ago
{
@@ -228,15 +246,15 @@
}
public void close()
- throws SQLException
+ throws SQLException
{
try
{
clearAllocatedStatements();
m_connection.clearWarnings();
- m_pool.put( this );
+ m_pool.put( (Poolable)m_proxy );
}
- catch ( SQLException se )
+ catch( SQLException se )
{
// gets rid of connections that throw SQLException during
// clean up
@@ -267,7 +285,7 @@
final Iterator iterator = m_allocatedStatements.iterator();
while( iterator.hasNext() )
{
- Statement stmt = (Statement) iterator.next();
+ Statement stmt = (Statement)iterator.next();
stmt.close();
}
}
@@ -305,22 +323,37 @@
}
}
}
-
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable
+
+ public boolean equals( Object obj )
+ {
+ if( Proxy.isProxyClass( obj.getClass() ) )
+ {
+ final InvocationHandler handler = Proxy.getInvocationHandler(obj );
+
+ if( handler instanceof ProxiedJdbcConnection )
+ {
+ return m_connection.equals( ( (ProxiedJdbcConnection)handler ).getConnection() );
+ }
+ }
+
+ return false;
+ }
+
+ public Object invoke( Object proxy, Method method, Object[] args )
+ throws Throwable
{
Object retVal = null;
- Method executeMethod = (Method)m_methods.get(method.getName());
-
- if ( null == executeMethod )
+ Method executeMethod = (Method)m_methods.get( method.getName() );
+
+ if( null == executeMethod )
{
- retVal = method.invoke(m_connection, args);
+ retVal = method.invoke( m_connection, args );
}
else
{
- retVal = executeMethod.invoke(this, args);
+ retVal = executeMethod.invoke( this, args );
}
-
+
return retVal;
}
}
1.19 +287 -276 avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource/JdbcConnectionFactory.java
Index: JdbcConnectionFactory.java
===================================================================
RCS file: /home/cvs/avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource/JdbcConnectionFactory.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- JdbcConnectionFactory.java 5 Mar 2003 18:59:01 -0000 1.18
+++ JdbcConnectionFactory.java 8 Apr 2003 18:34:34 -0000 1.19
@@ -1,276 +1,287 @@
-/*
-
- ============================================================================
- The Apache Software License, Version 1.1
- ============================================================================
-
- Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- 3. The end-user documentation included with the redistribution, if any, must
- include the following acknowledgment: "This product includes software
- developed by the Apache Software Foundation (http://www.apache.org/)."
- Alternately, this acknowledgment may appear in the software itself, if
- and wherever such third-party acknowledgments normally appear.
-
- 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
- must not be used to endorse or promote products derived from this software
- without prior written permission. For written permission, please contact
- apache@apache.org.
-
- 5. Products derived from this software may not be called "Apache", nor may
- "Apache" appear in their name, without prior written permission of the
- Apache Software Foundation.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- This software consists of voluntary contributions made by many individuals
- on behalf of the Apache Software Foundation. For more information on the
- Apache Software Foundation, please see <http://www.apache.org/>.
-
-*/
-package org.apache.avalon.excalibur.datasource;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.sql.Connection;
-import java.sql.DriverManager;
-
-import org.apache.avalon.excalibur.pool.ObjectFactory;
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.container.ContainerUtil;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.logger.LogEnabled;
-
-/**
- * The Factory implementation for JdbcConnections.
- *
- * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
- * @version CVS $Revision$ $Date$
- * @since 4.0
- */
-public class JdbcConnectionFactory extends AbstractLogEnabled implements ObjectFactory
-{
- private final String m_dburl;
- private final String m_username;
- private final String m_password;
- private final boolean m_autoCommit;
- private final String m_keepAlive;
- private final String m_connectionClass;
- private Class m_class;
- private static final String DEFAULT_KEEPALIVE = "SELECT 1";
- private static final String ORACLE_KEEPALIVE = JdbcConnectionFactory.DEFAULT_KEEPALIVE + " FROM DUAL";
- private Connection m_firstConnection;
-
- /**
- * @deprecated Use the new constructor with the keepalive and connectionClass
- * specified.
- */
- public JdbcConnectionFactory( final String url,
- final String username,
- final String password,
- final boolean autoCommit,
- final boolean oradb )
- {
- this( url, username, password, autoCommit, oradb, null );
- }
-
- /**
- * @deprecated Use the new constructor with the keepalive and connectionClass
- * specified.
- */
- public JdbcConnectionFactory( final String url,
- final String username,
- final String password,
- final boolean autoCommit,
- final boolean oradb,
- final String connectionClass )
- {
- this( url, username, password, autoCommit, ( oradb ) ? JdbcConnectionFactory.ORACLE_KEEPALIVE : JdbcConnectionFactory.DEFAULT_KEEPALIVE, connectionClass );
- }
-
- /**
- * Creates and configures a new JdbcConnectionFactory.
- *
- * @param url full JDBC database url.
- * @param username username to use when connecting to the database.
- * @param password password to use when connecting to the database.
- * @param autoCommit true if connections to the database should operate with auto commit
- * enabled.
- * @param keepAlive a query which will be used to check the statis of a connection after it
- * has been idle. A null value will cause the keep alive feature to
- * be disabled.
- * @param connectionClass class of connections created by the factory.
- */
- public JdbcConnectionFactory( final String url,
- final String username,
- final String password,
- final boolean autoCommit,
- final String keepAlive,
- final String connectionClass )
- {
- this.m_dburl = url;
- this.m_username = username;
- this.m_password = password;
- this.m_autoCommit = autoCommit;
- this.m_keepAlive = keepAlive;
- this.m_connectionClass = connectionClass;
-
- try
- {
- if( null == m_username )
- {
- m_firstConnection = DriverManager.getConnection( m_dburl );
- }
- else
- {
- m_firstConnection = DriverManager.getConnection( m_dburl, m_username, m_password );
- }
-
- init( m_firstConnection );
- }
- catch( Exception e )
- {
- // ignore for now
- // No logger here, so we can't log this. Really should output something here though
- // as it can be a real pain to track down the cause when this happens.
- //System.out.println( "Unable to get specified connection class: " + e );
- }
- }
-
- private void init( Connection connection ) throws Exception
- {
- String className = m_connectionClass;
- if( null == className )
- {
- m_class = AbstractJdbcConnection.class;
- }
- else
- {
- m_class = Thread.currentThread().getContextClassLoader().loadClass( className );
- }
- }
-
- public Object newInstance() throws Exception
- {
- Connection jdbcConnection = null;
- Connection connection = m_firstConnection;
-
- if( null == connection )
- {
- if( null == m_username )
- {
- connection = DriverManager.getConnection( m_dburl );
- }
- else
- {
- connection = DriverManager.getConnection( m_dburl, m_username, m_password );
- }
- }
- else
- {
- m_firstConnection = null;
- }
-
- if( null == this.m_class )
- {
- try
- {
- init( connection );
- }
- catch( Exception e )
- {
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "Exception in JdbcConnectionFactory.newInstance:", e );
- }
- throw new NoValidConnectionException( "No valid JdbcConnection class available" );
- }
- }
-
- try
- {
- jdbcConnection = getProxy(connection, this.m_keepAlive);
- }
- catch( Exception e )
- {
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "Exception in JdbcConnectionFactory.newInstance:", e );
- }
-
- throw new NoValidConnectionException( e.getMessage() );
- }
-
- ContainerUtil.enableLogging(jdbcConnection, getLogger());
-
- // Not all drivers are friendly to explicitly setting autocommit
- if( jdbcConnection.getAutoCommit() != m_autoCommit )
- {
- jdbcConnection.setAutoCommit( m_autoCommit );
- }
-
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "JdbcConnection object created" );
- }
-
- return jdbcConnection;
- }
-
- public Class getCreatedClass()
- {
- return m_class;
- }
-
- public void decommission( Object object ) throws Exception
- {
- if( object instanceof AbstractJdbcConnection )
- {
- ( (AbstractJdbcConnection)object ).dispose();
- }
- }
-
- private Connection getProxy(Connection conn, String keepAlive)
- {
- InvocationHandler handler = null;
-
- try
- {
- Constructor builder = m_class.getConstructor(new Class[]{Connection.class, String.class});
- handler = (InvocationHandler)builder.newInstance(new Object[]{conn, keepAlive});
- }
- catch (Exception e)
- {
- getLogger().error("Could not create the proper invocation handler, defaulting to AbstractJdbcConnection", e);
- handler = new AbstractJdbcConnection(conn, keepAlive);
- }
-
- return (Connection) Proxy.newProxyInstance(
- m_class.getClassLoader(),
- new Class[]{Connection.class,
- LogEnabled.class,
- PoolSettable.class,
- Disposable.class},
- handler);
- }
-}
+/*
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Jakarta", "Avalon", "Excalibur" and "Apache Software Foundation"
+ must not be used to endorse or promote products derived from this software
+ without prior written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation. For more information on the
+ Apache Software Foundation, please see <http://www.apache.org/>.
+
+*/
+package org.apache.avalon.excalibur.datasource;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.apache.avalon.excalibur.pool.ObjectFactory;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.LogEnabled;
+
+/**
+ * The Factory implementation for JdbcConnections.
+ *
+ * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
+ * @version CVS $Revision$ $Date$
+ * @since 4.0
+ */
+public class JdbcConnectionFactory extends AbstractLogEnabled implements ObjectFactory
+{
+ private final String m_dburl;
+ private final String m_username;
+ private final String m_password;
+ private final boolean m_autoCommit;
+ private final String m_keepAlive;
+ private final String m_connectionClass;
+ private Class m_class;
+ private static final String DEFAULT_KEEPALIVE = "SELECT 1";
+ private static final String ORACLE_KEEPALIVE = JdbcConnectionFactory.DEFAULT_KEEPALIVE + " FROM DUAL";
+ private Connection m_firstConnection;
+
+ /**
+ * @deprecated Use the new constructor with the keepalive and connectionClass
+ * specified.
+ */
+ public JdbcConnectionFactory( final String url,
+ final String username,
+ final String password,
+ final boolean autoCommit,
+ final boolean oradb )
+ {
+ this( url, username, password, autoCommit, oradb, null );
+ }
+
+ /**
+ * @deprecated Use the new constructor with the keepalive and connectionClass
+ * specified.
+ */
+ public JdbcConnectionFactory( final String url,
+ final String username,
+ final String password,
+ final boolean autoCommit,
+ final boolean oradb,
+ final String connectionClass )
+ {
+ this( url, username, password, autoCommit, ( oradb ) ? JdbcConnectionFactory.ORACLE_KEEPALIVE : JdbcConnectionFactory.DEFAULT_KEEPALIVE, connectionClass );
+ }
+
+ /**
+ * Creates and configures a new JdbcConnectionFactory.
+ *
+ * @param url full JDBC database url.
+ * @param username username to use when connecting to the database.
+ * @param password password to use when connecting to the database.
+ * @param autoCommit true if connections to the database should operate with auto commit
+ * enabled.
+ * @param keepAlive a query which will be used to check the statis of a connection after it
+ * has been idle. A null value will cause the keep alive feature to
+ * be disabled.
+ * @param connectionClass class of connections created by the factory.
+ */
+ public JdbcConnectionFactory( final String url,
+ final String username,
+ final String password,
+ final boolean autoCommit,
+ final String keepAlive,
+ final String connectionClass )
+ {
+ this.m_dburl = url;
+ this.m_username = username;
+ this.m_password = password;
+ this.m_autoCommit = autoCommit;
+ this.m_keepAlive = keepAlive;
+ this.m_connectionClass = connectionClass;
+
+ try
+ {
+ if( null == m_username )
+ {
+ m_firstConnection = DriverManager.getConnection( m_dburl );
+ }
+ else
+ {
+ m_firstConnection = DriverManager.getConnection( m_dburl, m_username, m_password );
+ }
+
+ init();
+ }
+ catch( Exception e )
+ {
+ // ignore for now
+ // No logger here, so we can't log this. Really should output something here though
+ // as it can be a real pain to track down the cause when this happens.
+ //System.out.println( "Unable to get specified connection class: " + e );
+ }
+ }
+
+ private void init() throws Exception
+ {
+ String className = m_connectionClass;
+ if( null == className )
+ {
+ m_class = AbstractJdbcConnection.class;
+ }
+ else
+ {
+ m_class = Thread.currentThread().getContextClassLoader().loadClass( className );
+ }
+ }
+
+ public Object newInstance() throws Exception
+ {
+ Connection jdbcConnection = null;
+ Connection connection = m_firstConnection;
+
+ if( null == connection )
+ {
+ if( null == m_username )
+ {
+ connection = DriverManager.getConnection( m_dburl );
+ }
+ else
+ {
+ connection = DriverManager.getConnection( m_dburl, m_username, m_password );
+ }
+ }
+ else
+ {
+ m_firstConnection = null;
+ }
+
+ if( null == this.m_class )
+ {
+ try
+ {
+ init();
+ }
+ catch( Exception e )
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "Exception in JdbcConnectionFactory.newInstance:", e );
+ }
+ throw new NoValidConnectionException( "No valid JdbcConnection class available" );
+ }
+ }
+
+ try
+ {
+ jdbcConnection = getProxy( connection, this.m_keepAlive );
+ }
+ catch( Exception e )
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "Exception in JdbcConnectionFactory.newInstance:", e );
+ }
+
+ throw new NoValidConnectionException( e.getMessage() );
+ }
+
+ ContainerUtil.enableLogging( jdbcConnection, getLogger() );
+
+ // Not all drivers are friendly to explicitly setting autocommit
+ if( jdbcConnection.getAutoCommit() != m_autoCommit )
+ {
+ jdbcConnection.setAutoCommit( m_autoCommit );
+ }
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "JdbcConnection object created" );
+ }
+
+ return jdbcConnection;
+ }
+
+ public Class getCreatedClass()
+ {
+ return m_class;
+ }
+
+ public void decommission( Object object ) throws Exception
+ {
+ if( object instanceof Disposable )
+ {
+ ( (Disposable)object ).dispose();
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "JdbcConnection object disposed" );
+ }
+ }
+ }
+
+ private Connection getProxy( Connection conn, String keepAlive )
+ {
+ ProxiedJdbcConnection handler = null;
+
+ try
+ {
+ Constructor builder = m_class.getConstructor( new Class[]{Connection.class,
+ String.class} );
+ handler = (ProxiedJdbcConnection)builder.newInstance( new Object[]{conn, keepAlive} );
+ }
+ catch( Exception e )
+ {
+ final String msg = "Could not create the proper invocation handler, "
+ + "defaulting to AbstractJdbcConnection";
+ getLogger().error( msg, e );
+ handler = new AbstractJdbcConnection( conn, keepAlive );
+ }
+
+ final Connection connection = (Connection)Proxy.newProxyInstance(
+ m_class.getClassLoader(),
+ new Class[]{Connection.class,
+ LogEnabled.class,
+ PoolSettable.class,
+ Disposable.class},
+ handler );
+
+ handler.setProxiedConnection( connection );
+
+ return connection;
+ }
+}
1.1 avalon-excalibur/datasource/src/java/org/apache/avalon/excalibur/datasource/ProxiedJdbcConnection.java
Index: ProxiedJdbcConnection.java
===================================================================
package org.apache.avalon.excalibur.datasource;
import java.lang.reflect.InvocationHandler;
import java.sql.Connection;
/**
* A JDBC connection that has a proxy around it in order to dynamicly implement JDBC2/3 needs
* to get a handle to its proxied self so that the proxied version can be returned to the pool.
*
* @author <a href="proyal@apache.org">peter royal</a>
*/
public interface ProxiedJdbcConnection extends InvocationHandler
{
void setProxiedConnection( Object proxy );
Connection getConnection();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org