Author: fhanik
Date: Tue Mar 20 15:45:19 2012
New Revision: 1302948

URL: http://svn.apache.org/viewvc?rev=1302948&view=rev
Log:
https://issues.apache.org/bugzilla/show_bug.cgi?id=52002 add in ability to 
configure pool so that connections can not be reused

Added:
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
    
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
Modified:
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
    
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
 Tue Mar 20 15:45:19 2012
@@ -312,7 +312,12 @@ public class ConnectionPool {
             getProxyConstructor(con.getXAConnection() != null);
             //create the proxy
             //TODO possible optimization, keep track if this connection was 
returned properly, and don't generate a new facade
-            Connection connection = 
(Connection)proxyClassConstructor.newInstance(new Object[] { handler });
+            Connection connection = null;
+            if (getPoolProperties().getUseDisposableConnectionFacade() ) {
+                connection = (Connection)proxyClassConstructor.newInstance(new 
Object[] { new DisposableConnectionFacade(handler) });
+            } else {
+                connection = (Connection)proxyClassConstructor.newInstance(new 
Object[] {handler});
+            }
             //return the connection
             return connection;
         }catch (Exception x) {

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
 Tue Mar 20 15:45:19 2012
@@ -1226,4 +1226,20 @@ public class DataSourceProxy implements 
         return getPoolProperties().getRollbackOnReturn();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean 
useDisposableConnectionFacade) {
+        
getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
 }

Added: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java?rev=1302948&view=auto
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
 (added)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
 Tue Mar 20 15:45:19 2012
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.jdbc.pool;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+/**
+ * A DisposableConnectionFacade object is the top most interceptor that wraps 
an object of type
+ * {@link PooledConnection}. The ProxyCutOffConnection intercepts two methods:
+ * <ul>
+ *   <li>{@link java.sql.Connection#close()} - returns the connection to the 
pool then breaks the link between cutoff and the next interceptor. May be 
called multiple times.</li>
+ *   <li>{@link java.lang.Object#toString()} - returns a custom string for 
this object</li>
+ * </ul>
+ * By default method comparisons is done on a String reference level, unless 
the {@link PoolConfiguration#setUseEquals(boolean)} has been called
+ * with a <code>true</code> argument.
+ * @author Kevin Grainer
+ */
+public class DisposableConnectionFacade extends JdbcInterceptor {
+    protected DisposableConnectionFacade(JdbcInterceptor interceptor) throws 
SQLException {
+        setUseEquals(interceptor.isUseEquals());
+        setNext(interceptor);
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
+        if (compare(ISCLOSED_VAL, method) && getNext() == null) {
+            return Boolean.TRUE;
+        }
+        if (compare(CLOSE_VAL, method) && getNext() == null) {
+            return null;
+        }
+
+        try {
+            return super.invoke(proxy, method, args);
+        } catch (NullPointerException e) {
+            if (getNext() == null) {
+                if (compare(TOSTRING_VAL, method)) {
+                    return "DisposableConnectionFacade[null]";
+                }
+                throw new SQLException("Connection has already been closed.");
+            }
+
+            throw e;
+        } finally {
+            if (compare(CLOSE_VAL, method)) {
+                setNext(null);
+            }
+        }
+    }
+}

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
 Tue Mar 20 15:45:19 2012
@@ -70,7 +70,7 @@ public abstract class JdbcInterceptor im
     /**
      * The next interceptor in the chain
      */
-    private JdbcInterceptor next = null;
+    private volatile JdbcInterceptor next = null;
     /**
      * Property that decides how we do string comparison, default is to use
      * {@link String#equals(Object)}. If set to <code>false</code> then the

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
 Tue Mar 20 15:45:19 2012
@@ -821,4 +821,18 @@ public interface PoolConfiguration {
      */
     public boolean getRollbackOnReturn();
 
+    /**
+     * If set to true, the connection will be wrapped with facade that will 
disallow the connection to be used after
+     * {@link java.sql.Connection#close()} is called. If set to true, after 
{@link java.sql.Connection#close()} all calls except
+     * {@link java.sql.Connection#close()} and {@link 
java.sql.Connection#isClosed()} will throw an exception.
+     * @param useDisposableConnectionFacade
+     */
+    public void setUseDisposableConnectionFacade(boolean 
useDisposableConnectionFacade);
+    /**
+     * Returns true if this connection pool is configured to use a connection 
facade to prevent re-use of connection after
+     * {@link java.sql.Connection#close()} has been invoked
+     * @return true if {@link java.sql.Connection#close()} has been invoked.
+     */
+    public boolean getUseDisposableConnectionFacade();
+
 }

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
 Tue Mar 20 15:45:19 2012
@@ -86,6 +86,7 @@ public class PoolProperties implements P
     protected boolean alternateUsernameAllowed = false;
     protected boolean commitOnReturn = false;
     protected boolean rollbackOnReturn = false;
+    protected boolean useDisposableConnectionFacade;
 
 
     /**
@@ -1194,4 +1195,29 @@ public class PoolProperties implements P
     public boolean getRollbackOnReturn() {
         return this.rollbackOnReturn;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean 
useDisposableConnectionFacade) {
+        this.useDisposableConnectionFacade = useDisposableConnectionFacade;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return useDisposableConnectionFacade;
+    }
+
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        // TODO Auto-generated method stub
+        return super.clone();
+    }
+
+
+
 }

Modified: 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
 Tue Mar 20 15:45:19 2012
@@ -777,5 +777,22 @@ public class ConnectionPool extends Noti
         return getPoolProperties().getRollbackOnReturn();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean 
useDisposableConnectionFacade) {
+        
getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
+
 
 }

Added: 
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java?rev=1302948&view=auto
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
 (added)
+++ 
tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
 Tue Mar 20 15:45:19 2012
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.jdbc.test;
+
+import java.sql.Connection;
+import org.apache.tomcat.jdbc.test.driver.Driver;
+
+public class MultipleCloseTest extends DefaultTestCase {
+
+    public MultipleCloseTest(String name) {
+        super(name);
+    }
+
+    @Override
+    public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
+        org.apache.tomcat.jdbc.pool.DataSource ds = 
super.createDefaultDataSource();
+        ds.getPoolProperties().setDriverClassName(Driver.class.getName());
+        ds.getPoolProperties().setUrl(Driver.url);
+        ds.getPoolProperties().setInitialSize(0);
+        ds.getPoolProperties().setMaxIdle(1);
+        ds.getPoolProperties().setMinIdle(1);
+        ds.getPoolProperties().setMaxActive(1);
+        ds.getPoolProperties().setUseDisposableConnectionFacade(true);
+        return ds;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        Driver.reset();
+        super.tearDown();
+    }
+
+    public void testClosedConnectionsNotReused() throws Exception {
+        this.init();
+
+        Connection con1 = datasource.getConnection();
+
+        // A new connection is open
+        assertFalse(con1.isClosed());
+
+        con1.close();
+
+        // Confirm that a closed connection is closed
+        assertTrue(con1.isClosed());
+
+        // Open a new connection (This will re-use the previous pooled 
connection)
+        datasource.getConnection();
+
+        // A connection, once closed, should stay closed
+        assertTrue(con1.isClosed());
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to