move over to an independent module
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Sat, 25 Oct 2008 00:06:20 +0000 (00:06 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Sat, 25 Oct 2008 00:06:20 +0000 (00:06 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@707794 13f79535-47bb-0310-9956-ffa450edef68

38 files changed:
extras.xml
java/org/apache/tomcat/jdbc/pool/ConnectionPool.java [deleted file]
java/org/apache/tomcat/jdbc/pool/DataSource.java [deleted file]
java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java [deleted file]
java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java [deleted file]
java/org/apache/tomcat/jdbc/pool/Driver.java [deleted file]
java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java [deleted file]
java/org/apache/tomcat/jdbc/pool/PoolProperties.java [deleted file]
java/org/apache/tomcat/jdbc/pool/PooledConnection.java [deleted file]
java/org/apache/tomcat/jdbc/pool/ProxyConnection.java [deleted file]
java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java [deleted file]
java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java [deleted file]
java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java [deleted file]
java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java [deleted file]
modules/jdbc-pool/build.xml [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/Driver.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java [new file with mode: 0644]
modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java [new file with mode: 0644]
modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java [new file with mode: 0644]
modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultProperties.java [new file with mode: 0644]
modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultTestCase.java [new file with mode: 0644]
modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestGCClose.java [new file with mode: 0644]
modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestTimeout.java [new file with mode: 0644]
test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java [deleted file]
test/org/apache/tomcat/jdbc/test/DefaultProperties.java [deleted file]
test/org/apache/tomcat/jdbc/test/DefaultTestCase.java [deleted file]
test/org/apache/tomcat/jdbc/test/TestGCClose.java [deleted file]
test/org/apache/tomcat/jdbc/test/TestTimeout.java [deleted file]

index be34de1..12a0ae1 100644 (file)
@@ -82,8 +82,6 @@
   <property name="cometd.war" value="${tomcat.extras}/cometd.war"/>
   <property name="tomcat-bayeux-samples.jar" value="${tomcat.extras}/tomcat-bayeux-samples.jar"/>
 
-  <property name="tomcat-jdbc.jar" value="${tomcat.extras}/tomcat-jdbc.jar"/>
-
   <property name="catalina-jmx-remote.jar" value="${tomcat.extras}/catalina-jmx-remote.jar"/>
        
   <!-- Classpath -->
@@ -333,31 +331,6 @@ To run the sample application, copy the following applications into your CATALIN
     </echo>
   </target>
 
-  <target name="conpool">
-    <mkdir dir="${tomcat.extras}"/>
-    <path id="tomcat.jdbc.classpath">
-      <pathelement path="${tomcat.classpath}"/>
-    </path>
-
-    <!-- compile org.apache.tomcat.jdbc-->
-    <javac srcdir="java" destdir="${tomcat.classes}"
-           debug="${compile.debug}"
-           deprecation="${compile.deprecation}"
-           source="${compile.source}"
-           optimize="${compile.optimize}">
-      <classpath refid="tomcat.jdbc.classpath"/>
-      <include name="org/apache/tomcat/jdbc/**" />
-    </javac>
-    
-    <!-- Cometd API JAR File -->
-    <jar jarfile="${tomcat-jdbc.jar}">
-      <fileset dir="${tomcat.classes}">
-        <include name="org/apache/tomcat/jdbc/**" />
-      </fileset>
-    </jar>
-    <!-- create checksums -->
-    <checksum file="${tomcat-jdbc.jar}" forceOverwrite="yes" fileext=".md5" />
-  </target>
 
 
   <target name="jmx-remote" >
diff --git a/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
deleted file mode 100644 (file)
index 1b594f3..0000000
+++ /dev/null
@@ -1,715 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-import java.lang.management.ManagementFactory;\r
-import java.lang.reflect.Constructor;\r
-import java.lang.reflect.InvocationHandler;\r
-import java.lang.reflect.Proxy;\r
-import java.sql.Connection;\r
-import java.sql.SQLException;\r
-import java.util.ConcurrentModificationException;\r
-import java.util.Iterator;\r
-import java.util.Queue;\r
-import java.util.concurrent.ArrayBlockingQueue;\r
-import java.util.concurrent.BlockingQueue;\r
-import java.util.concurrent.TimeUnit;\r
-\r
-import org.apache.juli.logging.Log;\r
-import org.apache.juli.logging.LogFactory;\r
-\r
-import org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean;\r
-\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-\r
-import javax.management.InstanceAlreadyExistsException;\r
-import javax.management.MBeanRegistrationException;\r
-import javax.management.MBeanServer;\r
-import javax.management.MalformedObjectNameException;\r
-import javax.management.NotCompliantMBeanException;\r
-import javax.management.ObjectName;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-\r
-public class ConnectionPool {\r
-\r
-    //logger\r
-    protected static Log log = LogFactory.getLog(ConnectionPool.class);\r
-\r
-    //===============================================================================\r
-    //         INSTANCE/QUICK ACCESS VARIABLE\r
-    //===============================================================================\r
-\r
-    /**\r
-     * All the information about the connection pool\r
-     */\r
-    protected PoolProperties poolProperties;\r
-\r
-    /**\r
-     * Contains all the connections that are in use\r
-     */\r
-    protected BlockingQueue<PooledConnection> busy;\r
-\r
-    /**\r
-     * Contains all the idle connections\r
-     */\r
-    protected BlockingQueue<PooledConnection> idle;\r
-\r
-    /**\r
-     * The thread that is responsible for checking abandoned and idle threads\r
-     */\r
-    protected PoolCleaner poolCleaner;\r
-\r
-    /**\r
-     * Pool closed flag\r
-     */\r
-    protected boolean closed = false;\r
-\r
-    /**\r
-     * Size of the pool\r
-     */\r
-    protected AtomicInteger size = new AtomicInteger(0);\r
-\r
-    /**\r
-     * Since newProxyInstance performs the same operation, over and over\r
-     * again, it is much more optimized if we simply store the constructor ourselves.\r
-     */\r
-    protected Constructor proxyClassConstructor;\r
-\r
-\r
-    //===============================================================================\r
-    //         PUBLIC METHODS\r
-    //===============================================================================\r
-\r
-    /**\r
-     * Instantiate a connection pool. This will create connections if initialSize is larger than 0\r
-     * @param prop PoolProperties - all the properties for this connection pool\r
-     * @throws SQLException\r
-     */\r
-    public ConnectionPool(PoolProperties prop) throws SQLException {\r
-        //setup quick access variables and pools\r
-        init(prop);\r
-    }\r
-\r
-    /**\r
-     * Borrows a connection from the pool\r
-     * @return Connection - a java.sql.Connection reflection proxy, wrapping the underlying object.\r
-     * @throws SQLException\r
-     */\r
-    public Connection getConnection() throws SQLException {\r
-        //check out a connection\r
-        PooledConnection con = (PooledConnection)borrowConnection();\r
-        JdbcInterceptor handler = con.getHandler();\r
-        if (handler==null) {\r
-            //build the proxy handler\r
-            handler = new ProxyConnection(this,con);\r
-            //set up the interceptor chain\r
-            String[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();\r
-            for (int i=proxies.length-1; i>=0; i--) {\r
-                try {\r
-                    JdbcInterceptor interceptor =\r
-                        (JdbcInterceptor) Class.forName(proxies[i], true,\r
-                                Thread.currentThread().getContextClassLoader()).newInstance();\r
-                    interceptor.setNext(handler);\r
-                    handler = interceptor;\r
-                }catch(Exception x) {\r
-                    SQLException sx = new SQLException("Unable to instantiate interceptor chain.");\r
-                    sx.initCause(x);\r
-                    throw sx;\r
-                }\r
-            }\r
-            //cache handler for the next iteration\r
-            con.setHandler(handler);\r
-        } else {\r
-            JdbcInterceptor next = handler;\r
-            //we have a cached handler, reset it\r
-            while (next!=null) {\r
-                next.reset(this, con);\r
-                next = next.getNext();\r
-            }\r
-        }\r
-\r
-        try {\r
-            //cache the constructor\r
-            if (proxyClassConstructor == null ) {\r
-                Class proxyClass = Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class});\r
-                proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });\r
-            }\r
-            //create the proxy\r
-            //TODO possible optimization, keep track if this connection was returned properly, and don't generate a new facade\r
-            Connection connection = (Connection)proxyClassConstructor.newInstance(new Object[] { handler });\r
-            //return the connection\r
-            return connection;\r
-        }catch (Exception x) {\r
-            throw new SQLException();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns the name of this pool\r
-     * @return String\r
-     */\r
-    public String getName() {\r
-        return getPoolProperties().getPoolName();\r
-    }\r
-\r
-    /**\r
-     * Returns the pool properties associated with this connection pool\r
-     * @return PoolProperties\r
-     */\r
-    public PoolProperties getPoolProperties() {\r
-        return this.poolProperties;\r
-    }\r
-\r
-    /**\r
-     * Returns the total size of this pool, this includes both busy and idle connections\r
-     * @return int\r
-     */\r
-    public int getSize() {\r
-        return idle.size()+busy.size();\r
-    }\r
-\r
-    /**\r
-     * Returns the number of connections that are in use\r
-     * @return int\r
-     */\r
-    public int getActive() {\r
-        return busy.size();\r
-    }\r
-\r
-    public int getIdle() {\r
-        return idle.size();\r
-    }\r
-\r
-    /**\r
-     * Returns true if {@link #close close} has been called, and the connection pool is unusable\r
-     * @return boolean\r
-     */\r
-    public  boolean isClosed() {\r
-        return this.closed;\r
-    }\r
-\r
-    @Override\r
-    protected void finalize() throws Throwable {\r
-        close(true);\r
-    }\r
-\r
-    /**\r
-     * Closes the pool and all disconnects all idle connections\r
-     * Active connections will be closed upon the {@link java.sql.Connection#close close} method is called\r
-     * on the underlying connection instead of being returned to the pool\r
-     * @param force - true to even close the active connections\r
-     */\r
-    protected void close(boolean force) {\r
-        //are we already closed\r
-        if (this.closed) return;\r
-        //prevent other threads from entering\r
-        this.closed = true;\r
-        //stop background thread\r
-        if (poolCleaner!=null) {\r
-            poolCleaner.stopRunning();\r
-        }\r
-\r
-        /* release all idle connections */\r
-        BlockingQueue<PooledConnection> pool = (idle.size()>0)?idle:(force?busy:idle);\r
-        while (pool.size()>0) {\r
-            try {\r
-                //retrieve the next connection\r
-                PooledConnection con = pool.poll(1000, TimeUnit.MILLISECONDS);\r
-                //close it and retrieve the next one, if one is available\r
-                while (con != null) {\r
-                    //close the connection\r
-                    if (pool==idle)\r
-                        release(con);\r
-                    else\r
-                        abandon(con);\r
-                    con = pool.poll(1000, TimeUnit.MILLISECONDS);\r
-                } //while\r
-            } catch (InterruptedException ex) {\r
-                Thread.currentThread().interrupted();\r
-            }\r
-            if (pool.size()==0 && force && pool!=busy) pool = busy;\r
-        }\r
-        size.set(0);\r
-        if (this.getPoolProperties().isJmxEnabled()) stopJmx();\r
-    } //closePool\r
-\r
-\r
-    //===============================================================================\r
-    //         PROTECTED METHODS\r
-    //===============================================================================\r
-    /**\r
-     * Initialize the connection pool - called from the constructor\r
-     * @param properties PoolProperties - properties used to initialize the pool with\r
-     * @throws SQLException\r
-     */\r
-    protected void init (PoolProperties properties) throws SQLException {\r
-        poolProperties = properties;\r
-        //make space for 10 extra in case we flow over a bit\r
-        busy = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);\r
-        //make space for 10 extra in case we flow over a bit\r
-        idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);\r
-\r
-        //if the evictor thread is supposed to run, start it now\r
-        if (properties.isPoolSweeperEnabled()) {\r
-            poolCleaner = new PoolCleaner("[Pool-Cleaner]:" + properties.getName(), this, properties.getTimeBetweenEvictionRunsMillis());\r
-            poolCleaner.start();\r
-        } //end if\r
-\r
-        if (properties.getMaxActive()<properties.getInitialSize()) {\r
-            log.warn("initialSize is larger than maxActive, setting initialSize to: "+properties.getMaxActive());\r
-            properties.setInitialSize(properties.getMaxActive());\r
-        }\r
-        if (properties.getMinIdle()>properties.getMaxActive()) {\r
-            log.warn("minIdle is larger than maxActive, setting minIdle to: "+properties.getMaxActive());\r
-            properties.setMinIdle(properties.getMaxActive());\r
-        }\r
-        if (properties.getMaxIdle()>properties.getMaxActive()) {\r
-            log.warn("maxIdle is larger than maxActive, setting maxIdle to: "+properties.getMaxActive());\r
-            properties.setMaxIdle(properties.getMaxActive());\r
-        }\r
-        if (properties.getMaxIdle()<properties.getMinIdle()) {\r
-            log.warn("maxIdle is smaller than minIdle, setting maxIdle to: "+properties.getMinIdle());\r
-            properties.setMaxIdle(properties.getMinIdle());\r
-        }\r
-\r
-\r
-        //initialize the pool with its initial set of members\r
-        PooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()];\r
-        try {\r
-            for (int i = 0; i < initialPool.length; i++) {\r
-                initialPool[i] = this.borrowConnection();\r
-            } //for\r
-\r
-        } catch (SQLException x) {\r
-            close(true);\r
-            throw x;\r
-        } finally {\r
-            //return the members as idle to the pool\r
-            for (int i = 0; i < initialPool.length; i++) {\r
-                if (initialPool[i] != null) {\r
-                    try {this.returnConnection(initialPool[i]);}catch(Exception x){}\r
-                } //end if\r
-            } //for\r
-        } //catch\r
-        if (this.getPoolProperties().isJmxEnabled()) startJmx();\r
-        closed = false;\r
-    }\r
-\r
-\r
-//===============================================================================\r
-//         CONNECTION POOLING IMPL\r
-//===============================================================================\r
-\r
-    /**\r
-     * thread safe way to abandon a connection\r
-     * signals a connection to be abandoned.\r
-     * this will disconnect the connection, and log the stack trace if logAbanded=true\r
-     * @param con PooledConnection\r
-     */\r
-    protected void abandon(PooledConnection con) {\r
-        if (con == null)\r
-            return;\r
-        try {\r
-            con.lock();\r
-            if (getPoolProperties().isLogAbandoned()) {\r
-                log.warn("Connection has been abandoned" + con + ":" +con.getStackTrace());\r
-            }\r
-            con.abandon();\r
-        } finally {\r
-            con.unlock();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * thread safe way to release a connection\r
-     * @param con PooledConnection\r
-     */\r
-    protected void release(PooledConnection con) {\r
-        if (con == null)\r
-            return;\r
-        try {\r
-            con.lock();\r
-            con.release();\r
-        } finally {\r
-            con.unlock();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Thread safe way to retrieve a connection from the pool\r
-     * @return PooledConnection\r
-     * @throws SQLException\r
-     */\r
-    protected PooledConnection borrowConnection() throws SQLException {\r
-\r
-        if (isClosed()) {\r
-            throw new SQLException("Connection pool closed.");\r
-        } //end if\r
-\r
-        //get the current time stamp\r
-        long now = System.currentTimeMillis();\r
-        //see if there is one available immediately\r
-        PooledConnection con = idle.poll();\r
-\r
-        while (true) {\r
-            if (con!=null) {\r
-                PooledConnection result = borrowConnection(now, con);\r
-                //validation might have failed, in which case null is returned\r
-                if (result!=null) return result;\r
-            }\r
-            if (size.get() < getPoolProperties().getMaxActive()) {\r
-                if (size.addAndGet(1) <= getPoolProperties().getMaxActive()) {\r
-                    return createConnection(now, con);\r
-                } else {\r
-                    size.addAndGet(-1); //restore the value, we didn't create a connection\r
-                }\r
-            } //end if\r
-\r
-            //calculate wait time for this iteration\r
-            long maxWait = (getPoolProperties().getMaxWait()<=0)?Long.MAX_VALUE:getPoolProperties().getMaxWait();\r
-            long timetowait = Math.max(1, maxWait - (System.currentTimeMillis() - now));\r
-            try {\r
-                //retrieve an existing connection\r
-                con = idle.poll(timetowait, TimeUnit.MILLISECONDS);\r
-            } catch (InterruptedException ex) {\r
-                Thread.currentThread().interrupted();\r
-            }\r
-            //we didn't get a connection, lets see if we timed out\r
-            if (con == null) {\r
-                if ((System.currentTimeMillis() - now) >= maxWait) {\r
-                    throw new SQLException(\r
-                        "Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +\r
-                        " seconds, none available["+busy.size()+" in use].");\r
-                } else {\r
-                    //no timeout, lets try again\r
-                    continue;\r
-                }\r
-            }\r
-        } //while\r
-    }\r
-\r
-    protected PooledConnection createConnection(long now, PooledConnection con) {\r
-        //no connections where available we'll create one\r
-        boolean error = false;\r
-        try {\r
-            //connect and validate the connection\r
-            con = create();\r
-            con.lock();\r
-            if (!busy.offer(con)) {\r
-                log.debug("Connection doesn't fit into busy array, connection will not be traceable.");\r
-            }\r
-            con.connect();\r
-            if (con.validate(PooledConnection.VALIDATE_INIT)) {\r
-                //no need to lock a new one, its not contented\r
-                con.setTimestamp(now);\r
-                if (getPoolProperties().isLogAbandoned()) {\r
-                    con.setStackTrace(getThreadDump());\r
-                }\r
-                return con;\r
-            } //end if\r
-        } catch (Exception e) {\r
-            error = true;\r
-            log.error("Unable to create a new JDBC connection.", e);\r
-        } finally {\r
-            if (error ) {\r
-                release(con);\r
-                busy.remove(con);\r
-            }\r
-            con.unlock();\r
-        }//catch\r
-        return null;\r
-    }\r
-\r
-    protected PooledConnection borrowConnection(long now, PooledConnection con) {\r
-        //we have a connection, lets set it up\r
-        boolean setToNull = false;\r
-        try {\r
-            con.lock();\r
-            if (con.isDiscarded()) {\r
-                //connection has already been disconnected\r
-                setToNull = true;\r
-            } else if (con.validate(PooledConnection.VALIDATE_BORROW)) {\r
-                //set the timestamp\r
-                con.setTimestamp(now);\r
-                if (getPoolProperties().isLogAbandoned()) {\r
-                    //set the stack trace for this pool\r
-                    con.setStackTrace(getThreadDump());\r
-                }\r
-                if (!busy.offer(con)) {\r
-                    log.debug("Connection doesn't fit into busy array, connection will not be traceable.");\r
-                }\r
-                return con;\r
-            } else {\r
-                /*if the object wasn't validated, we may as well remove it*/\r
-                release(con);\r
-                setToNull = true;\r
-            } //end if\r
-        } finally {\r
-            con.unlock();\r
-            if (setToNull) {\r
-                con = null;\r
-            }\r
-        }\r
-        return con;\r
-    }\r
-\r
-    /**\r
-     * Returns a connection to the pool\r
-     * @param con PooledConnection\r
-     */\r
-    protected void returnConnection(PooledConnection con) {\r
-        if (isClosed()) {\r
-            //if the connection pool is closed\r
-            //close the connection instead of returning it\r
-            release(con);\r
-            return;\r
-        } //end if\r
-\r
-        if (con != null) {\r
-            try {\r
-                con.lock();\r
-\r
-                if (busy.remove(con)) {\r
-                    if ((!con.isDiscarded()) && (!isClosed()) &&\r
-                            con.validate(PooledConnection.VALIDATE_RETURN)) {\r
-                        con.setStackTrace(null);\r
-                        con.setTimestamp(System.currentTimeMillis());\r
-                        if (!idle.offer(con)) {\r
-                            if (log.isDebugEnabled()) {\r
-                                log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle.offer failed.");\r
-                            }\r
-                            release(con);\r
-                        }\r
-                    } else {\r
-                        if (log.isDebugEnabled()) {\r
-                            log.debug("Connection ["+con+"] will be closed and not returned to the pool.");\r
-                        }\r
-                        release(con);\r
-                    } //end if\r
-                } else {\r
-                    if (log.isDebugEnabled()) {\r
-                        log.debug("Connection ["+con+"] will be closed and not returned to the pool, busy.remove failed.");\r
-                    }\r
-                    release(con);\r
-                }\r
-            } finally {\r
-                con.unlock();\r
-            }\r
-        } //end if\r
-    } //checkIn\r
-\r
-    public void checkAbandoned() {\r
-        try {\r
-            long now = System.currentTimeMillis();\r
-            Iterator<PooledConnection> locked = busy.iterator();\r
-            while (locked.hasNext()) {\r
-                PooledConnection con = locked.next();\r
-                boolean setToNull = false;\r
-                try {\r
-                    con.lock();\r
-                    //the con has been returned to the pool\r
-                    //ignore it\r
-                    if (idle.contains(con))\r
-                        continue;\r
-                    long time = con.getTimestamp();\r
-                    if ((now - time) > con.getAbandonTimeout()) {\r
-                        busy.remove(con);\r
-                        abandon(con);\r
-                        release(con);\r
-                        setToNull = true;\r
-                    } else {\r
-                        //do nothing\r
-                    } //end if\r
-                } finally {\r
-                    con.unlock();\r
-                    if (setToNull)\r
-                        con = null;\r
-                }\r
-            } //while\r
-        } catch (ConcurrentModificationException e) {\r
-            log.debug("checkAbandoned failed." ,e);\r
-        } catch (Exception e) {\r
-            log.warn("checkAbandoned failed, it will be retried.",e);\r
-        }\r
-    }\r
-\r
-    public void checkIdle() {\r
-        try {\r
-            long now = System.currentTimeMillis();\r
-            Iterator<PooledConnection> unlocked = idle.iterator();\r
-            while ( (idle.size()>=getPoolProperties().getMinIdle()) && unlocked.hasNext()) {\r
-                PooledConnection con = unlocked.next();\r
-                boolean setToNull = false;\r
-                try {\r
-                    con.lock();\r
-                    //the con been taken out, we can't clean it up\r
-                    if (busy.contains(con))\r
-                        continue;\r
-                    long time = con.getTimestamp();\r
-                    if (((now - time) > con.getReleaseTime()) && (getSize()>getPoolProperties().getMinIdle())) {\r
-                        release(con);\r
-                        idle.remove(con);\r
-                        setToNull = true;\r
-                    } else {\r
-                        //do nothing\r
-                    } //end if\r
-                } finally {\r
-                    con.unlock();\r
-                    if (setToNull)\r
-                        con = null;\r
-                }\r
-            } //while\r
-        } catch (ConcurrentModificationException e) {\r
-            log.debug("checkIdle failed." ,e);\r
-        } catch (Exception e) {\r
-            log.warn("checkIdle failed, it will be retried.",e);\r
-        }\r
-\r
-    }\r
-\r
-    public void testAllIdle() {\r
-        try {\r
-            Iterator<PooledConnection> unlocked = idle.iterator();\r
-            while (unlocked.hasNext()) {\r
-                PooledConnection con = unlocked.next();\r
-                try {\r
-                    con.lock();\r
-                    //the con been taken out, we can't clean it up\r
-                    if (busy.contains(con))\r
-                        continue;\r
-                    if (!con.validate(PooledConnection.VALIDATE_IDLE)) {\r
-                        idle.remove(con);\r
-                        con.release();\r
-                    }\r
-                } finally {\r
-                    con.unlock();\r
-                }\r
-            } //while\r
-        } catch (ConcurrentModificationException e) {\r
-            log.debug("testAllIdle failed." ,e);\r
-        } catch (Exception e) {\r
-            log.warn("testAllIdle failed, it will be retried.",e);\r
-        }\r
-\r
-    }\r
-\r
-\r
-    protected static String getThreadDump() {\r
-        Exception x = new Exception();\r
-        x.fillInStackTrace();\r
-        return getStackTrace(x);\r
-    }\r
-\r
-    protected static String getStackTrace(Exception x) {\r
-        if (x == null) {\r
-            return null;\r
-        } else {\r
-            java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();\r
-            java.io.PrintStream writer = new java.io.PrintStream(bout);\r
-            x.printStackTrace(writer);\r
-            String result = bout.toString();\r
-            return result;\r
-        } //end if\r
-    }\r
-\r
-\r
-    protected PooledConnection create() throws java.lang.Exception {\r
-        PooledConnection con = new PooledConnection(getPoolProperties(), this);\r
-        return con;\r
-    }\r
-\r
-    protected void finalize(PooledConnection con) {\r
-        size.addAndGet(-1);\r
-    }\r
-\r
-    public void startJmx() {\r
-        try {\r
-            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();\r
-            ObjectName name = new ObjectName("org.apache.tomcat.jdbc.pool.jmx:type=ConnectionPool,name="+getName());\r
-            mbs.registerMBean(new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this), name);\r
-        } catch (Exception x) {\r
-            log.warn("Unable to start JMX integration for connection pool. Instance["+getName()+"] can't be monitored.",x);\r
-        }\r
-    }\r
-\r
-    public void stopJmx() {\r
-        try {\r
-            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();\r
-            ObjectName name = new ObjectName("org.apache.tomcat.jdbc.pool.jmx:type=ConnectionPool,name="+getName());\r
-            mbs.unregisterMBean(name);\r
-        }catch (Exception x) {\r
-            log.warn("Unable to stop JMX integration for connection pool. Instance["+getName()+"].",x);\r
-        }\r
-    }\r
-\r
-\r
-    protected class PoolCleaner extends Thread {\r
-        protected ConnectionPool pool;\r
-        protected long sleepTime;\r
-        protected boolean run = true;\r
-        PoolCleaner(String name, ConnectionPool pool, long sleepTime) {\r
-            super(name);\r
-            this.setDaemon(true);\r
-            this.pool = pool;\r
-            this.sleepTime = sleepTime;\r
-            if (sleepTime <= 0) {\r
-                pool.log.warn("Database connection pool evicter thread interval is set to 0, defaulting to 30 seconds");\r
-                this.sleepTime = 1000 * 30;\r
-            } else if (sleepTime < 1000) {\r
-                pool.log.warn("Database connection pool evicter thread interval is set to lower than 1 second.");\r
-            }\r
-        }\r
-\r
-        public void run() {\r
-            while (run) {\r
-                try {\r
-                    sleep(sleepTime);\r
-                } catch (InterruptedException e) {\r
-                    // ignore it\r
-                    Thread.currentThread().interrupted();\r
-                    continue;\r
-                } //catch\r
-\r
-                if (pool.isClosed()) {\r
-                    if (pool.getSize() <= 0) {\r
-                        run = false;\r
-                    }\r
-                } else {\r
-                    try {\r
-                        if (pool.getPoolProperties().isRemoveAbandoned())\r
-                            pool.checkAbandoned();\r
-                        if (pool.getPoolProperties().getMaxIdle()<pool.idle.size())\r
-                            pool.checkIdle();\r
-                        if (pool.getPoolProperties().isTestWhileIdle())\r
-                            pool.testAllIdle();\r
-                    } catch (Exception x) {\r
-                        pool.log.error("", x);\r
-                    } //catch\r
-                } //end if\r
-            } //while\r
-        } //run\r
-\r
-        public void stopRunning() {\r
-            run = false;\r
-            interrupt();\r
-        }\r
-    }\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/DataSource.java b/java/org/apache/tomcat/jdbc/pool/DataSource.java
deleted file mode 100644 (file)
index 7241117..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-\r
-/**\r
- * A DataSource that can be instantiated through IoC and implements the DataSource interface\r
- * since the DataSourceProxy is used as a generic proxy\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class DataSource extends DataSourceProxy implements javax.sql.DataSource {\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java b/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
deleted file mode 100644 (file)
index 58265bf..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.lang.reflect.InvocationHandler;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Proxy;\r
-import java.sql.Connection;\r
-import java.util.HashMap;\r
-import java.util.Hashtable;\r
-import java.util.Properties;\r
-\r
-import javax.naming.Context;\r
-import javax.naming.Name;\r
-import javax.naming.RefAddr;\r
-import javax.naming.Reference;\r
-import javax.naming.spi.ObjectFactory;\r
-import javax.sql.DataSource;\r
-\r
-import org.apache.juli.logging.Log;\r
-import org.apache.juli.logging.LogFactory;\r
-\r
-/**\r
- * <p>JNDI object factory that creates an instance of\r
- * <code>BasicDataSource</code> that has been configured based on the\r
- * <code>RefAddr</code> values of the specified <code>Reference</code>,\r
- * which must match the names and data types of the\r
- * <code>BasicDataSource</code> bean properties.</p>\r
- * <br/>\r
- * Properties available for configuration:<br/>\r
- * <a href="http://commons.apache.org/dbcp/configuration.html">Commons DBCP properties</a><br/>\r
- *<ol>\r
- *  <li>initSQL - A query that gets executed once, right after the connection is established.</li>\r
- *  <li>testOnConnect - run validationQuery after connection has been established.</li>\r
- *  <li>validationInterval - avoid excess validation, only run validation at most at this frequency - time in milliseconds.</li>\r
- *  <li>jdbcInterceptors - a semicolon separated list of classnames extending {@link JdbcInterceptor} class.</li>\r
- *  <li>jmxEnabled - true of false, whether to register the pool with JMX.</li>\r
- *</ol>\r
- * @author Craig R. McClanahan\r
- * @author Dirk Verbeeck\r
- * @author Filip Hanik\r
- */\r
-public class DataSourceFactory implements ObjectFactory {\r
-    protected static Log log = LogFactory.getLog(DataSourceFactory.class);\r
-\r
-    protected final static String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";\r
-    protected final static String PROP_DEFAULTREADONLY = "defaultReadOnly";\r
-    protected final static String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";\r
-    protected final static String PROP_DEFAULTCATALOG = "defaultCatalog";\r
-    \r
-    protected final static String PROP_DRIVERCLASSNAME = "driverClassName";\r
-    protected final static String PROP_PASSWORD = "password";\r
-    protected final static String PROP_URL = "url";\r
-    protected final static String PROP_USERNAME = "username";\r
-\r
-    protected final static String PROP_MAXACTIVE = "maxActive";\r
-    protected final static String PROP_MAXIDLE = "maxIdle";\r
-    protected final static String PROP_MINIDLE = "minIdle";\r
-    protected final static String PROP_INITIALSIZE = "initialSize";\r
-    protected final static String PROP_MAXWAIT = "maxWait";\r
-    \r
-    protected final static String PROP_TESTONBORROW = "testOnBorrow";\r
-    protected final static String PROP_TESTONRETURN = "testOnReturn";\r
-    protected final static String PROP_TESTWHILEIDLE = "testWhileIdle";\r
-    protected final static String PROP_TESTONCONNECT = "testOnConnect";\r
-    protected final static String PROP_VALIDATIONQUERY = "validationQuery";\r
-    \r
-    protected final static String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";\r
-    protected final static String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";\r
-    protected final static String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";\r
-    \r
-    protected final static String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";\r
-    \r
-    protected final static String PROP_REMOVEABANDONED = "removeAbandoned";\r
-    protected final static String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";\r
-    protected final static String PROP_LOGABANDONED = "logAbandoned";\r
-    \r
-    protected final static String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";\r
-    protected final static String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";\r
-    protected final static String PROP_CONNECTIONPROPERTIES = "connectionProperties";\r
-    \r
-    protected final static String PROP_INITSQL = "initSQL";\r
-    protected final static String PROP_INTERCEPTORS = "jdbcInterceptors";\r
-    protected final static String PROP_VALIDATIONINTERVAL = "validationInterval";\r
-    protected final static String PROP_JMX_ENABLED = "jmxEnabled";\r
-    \r
-    public static final int UNKNOWN_TRANSACTIONISOLATION = -1;\r
-\r
-\r
-    protected final static String[] ALL_PROPERTIES = {\r
-        PROP_DEFAULTAUTOCOMMIT,\r
-        PROP_DEFAULTREADONLY,\r
-        PROP_DEFAULTTRANSACTIONISOLATION,\r
-        PROP_DEFAULTCATALOG,\r
-        PROP_DRIVERCLASSNAME,\r
-        PROP_MAXACTIVE,\r
-        PROP_MAXIDLE,\r
-        PROP_MINIDLE,\r
-        PROP_INITIALSIZE,\r
-        PROP_MAXWAIT,\r
-        PROP_TESTONBORROW,\r
-        PROP_TESTONRETURN,\r
-        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,\r
-        PROP_NUMTESTSPEREVICTIONRUN,\r
-        PROP_MINEVICTABLEIDLETIMEMILLIS,\r
-        PROP_TESTWHILEIDLE,\r
-        PROP_TESTONCONNECT,\r
-        PROP_PASSWORD,\r
-        PROP_URL,\r
-        PROP_USERNAME,\r
-        PROP_VALIDATIONQUERY,\r
-        PROP_VALIDATIONINTERVAL,\r
-        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,\r
-        PROP_REMOVEABANDONED,\r
-        PROP_REMOVEABANDONEDTIMEOUT,\r
-        PROP_LOGABANDONED,\r
-        PROP_POOLPREPAREDSTATEMENTS,\r
-        PROP_MAXOPENPREPAREDSTATEMENTS,\r
-        PROP_CONNECTIONPROPERTIES,\r
-        PROP_INITSQL,\r
-        PROP_INTERCEPTORS,\r
-        PROP_JMX_ENABLED\r
-    };\r
-\r
-    // -------------------------------------------------- ObjectFactory Methods\r
-\r
-    /**\r
-     * <p>Create and return a new <code>BasicDataSource</code> instance.  If no\r
-     * instance can be created, return <code>null</code> instead.</p>\r
-     *\r
-     * @param obj The possibly null object containing location or\r
-     *  reference information that can be used in creating an object\r
-     * @param name The name of this object relative to <code>nameCtx</code>\r
-     * @param nameCtx The context relative to which the <code>name</code>\r
-     *  parameter is specified, or <code>null</code> if <code>name</code>\r
-     *  is relative to the default initial context\r
-     * @param environment The possibly null environment that is used in\r
-     *  creating this object\r
-     *\r
-     * @exception Exception if an exception occurs creating the instance\r
-     */\r
-    public Object getObjectInstance(Object obj, Name name, Context nameCtx,\r
-                                    Hashtable environment) throws Exception {\r
-\r
-        // We only know how to deal with <code>javax.naming.Reference</code>s\r
-        // that specify a class name of "javax.sql.DataSource"\r
-        if ((obj == null) || !(obj instanceof Reference)) {\r
-            return null;\r
-        }\r
-        Reference ref = (Reference) obj;\r
-        if (!"javax.sql.DataSource".equals(ref.getClassName())) {\r
-            return null;\r
-        }\r
-\r
-        Properties properties = new Properties();\r
-        for (int i = 0; i < ALL_PROPERTIES.length; i++) {\r
-            String propertyName = ALL_PROPERTIES[i];\r
-            RefAddr ra = ref.get(propertyName);\r
-            if (ra != null) {\r
-                String propertyValue = ra.getContent().toString();\r
-                properties.setProperty(propertyName, propertyValue);\r
-            }\r
-        }\r
-\r
-        return createDataSource(properties);\r
-    }\r
-\r
-    /**\r
-     * Creates and configures a {@link BasicDataSource} instance based on the\r
-     * given properties.\r
-     *\r
-     * @param properties the datasource configuration properties\r
-     * @throws Exception if an error occurs creating the data source\r
-     */\r
-    public static DataSource createDataSource(Properties properties) throws Exception {\r
-        org.apache.tomcat.jdbc.pool.DataSourceProxy dataSource = new org.apache.tomcat.jdbc.pool.DataSourceProxy();\r
-\r
-        String value = null;\r
-\r
-        value = properties.getProperty(PROP_DEFAULTAUTOCOMMIT);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setDefaultAutoCommit(Boolean.valueOf(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_DEFAULTREADONLY);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setDefaultReadOnly(Boolean.valueOf(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_DEFAULTTRANSACTIONISOLATION);\r
-        if (value != null) {\r
-            int level = UNKNOWN_TRANSACTIONISOLATION;\r
-            if ("NONE".equalsIgnoreCase(value)) {\r
-                level = Connection.TRANSACTION_NONE;\r
-            } else if ("READ_COMMITTED".equalsIgnoreCase(value)) {\r
-                level = Connection.TRANSACTION_READ_COMMITTED;\r
-            } else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {\r
-                level = Connection.TRANSACTION_READ_UNCOMMITTED;\r
-            } else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {\r
-                level = Connection.TRANSACTION_REPEATABLE_READ;\r
-            } else if ("SERIALIZABLE".equalsIgnoreCase(value)) {\r
-                level = Connection.TRANSACTION_SERIALIZABLE;\r
-            } else {\r
-                try {\r
-                    level = Integer.parseInt(value);\r
-                } catch (NumberFormatException e) {\r
-                    System.err.println("Could not parse defaultTransactionIsolation: " + value);\r
-                    System.err.println("WARNING: defaultTransactionIsolation not set");\r
-                    System.err.println("using default value of database driver");\r
-                    level = UNKNOWN_TRANSACTIONISOLATION;\r
-                }\r
-            }\r
-            dataSource.getPoolProperties().setDefaultTransactionIsolation(level);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_DEFAULTCATALOG);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setDefaultCatalog(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_DRIVERCLASSNAME);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setDriverClassName(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MAXACTIVE);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setMaxActive(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MAXIDLE);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setMaxIdle(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MINIDLE);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setMinIdle(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_INITIALSIZE);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setInitialSize(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MAXWAIT);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setMaxWait(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_TESTONBORROW);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setTestOnBorrow(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_TESTONRETURN);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setTestOnReturn(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_TESTONCONNECT);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setTestOnConnect(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_TIMEBETWEENEVICTIONRUNSMILLIS);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setTimeBetweenEvictionRunsMillis(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_NUMTESTSPEREVICTIONRUN);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setNumTestsPerEvictionRun(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MINEVICTABLEIDLETIMEMILLIS);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setMinEvictableIdleTimeMillis(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_TESTWHILEIDLE);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setTestWhileIdle(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_PASSWORD);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setPassword(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_URL);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setUrl(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_USERNAME);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setUsername(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_VALIDATIONQUERY);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setValidationQuery(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_VALIDATIONINTERVAL);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setValidationInterval(Long.parseLong(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().\r
-                setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_REMOVEABANDONED);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setRemoveAbandoned(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_REMOVEABANDONEDTIMEOUT);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setRemoveAbandonedTimeout(Integer.parseInt(value));\r
-        }\r
-\r
-        value = properties.getProperty(PROP_LOGABANDONED);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setLogAbandoned(Boolean.valueOf(value).booleanValue());\r
-        }\r
-\r
-        value = properties.getProperty(PROP_POOLPREPAREDSTATEMENTS);\r
-        if (value != null) {\r
-            log.warn(PROP_POOLPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");\r
-        }\r
-\r
-        value = properties.getProperty(PROP_MAXOPENPREPAREDSTATEMENTS);\r
-        if (value != null) {\r
-            log.warn(PROP_MAXOPENPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");\r
-        }\r
-\r
-        value = properties.getProperty(PROP_CONNECTIONPROPERTIES);\r
-        if (value != null) {\r
-            Properties p = getProperties(value);\r
-            dataSource.getPoolProperties().setDbProperties(p);\r
-        } else {\r
-            dataSource.getPoolProperties().setDbProperties(new Properties());\r
-        }\r
-\r
-        dataSource.getPoolProperties().getDbProperties().setProperty("user",dataSource.getPoolProperties().getUsername());\r
-        dataSource.getPoolProperties().getDbProperties().setProperty("password",dataSource.getPoolProperties().getPassword());\r
-\r
-        value = properties.getProperty(PROP_INITSQL);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setInitSQL(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_INTERCEPTORS);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setJdbcInterceptors(value);\r
-        }\r
-\r
-        value = properties.getProperty(PROP_JMX_ENABLED);\r
-        if (value != null) {\r
-            dataSource.getPoolProperties().setJmxEnabled(Boolean.parseBoolean(value));\r
-        }\r
-\r
-        // Return the configured DataSource instance\r
-        DataSource ds = getDataSource(dataSource);\r
-        return ds;\r
-    }\r
-\r
-    public static DataSource getDataSource(org.apache.tomcat.jdbc.pool.DataSourceProxy dataSource) {\r
-        DataSourceHandler handler = new DataSourceHandler(dataSource);\r
-        DataSource ds = (DataSource)Proxy.newProxyInstance(DataSourceFactory.class.getClassLoader(), new Class[] {javax.sql.DataSource.class}, handler);\r
-        return ds;\r
-    }\r
-\r
-    /**\r
-     * <p>Parse properties from the string. Format of the string must be [propertyName=property;]*<p>\r
-     * @param propText\r
-     * @return Properties\r
-     * @throws Exception\r
-     */\r
-    static protected Properties getProperties(String propText) throws Exception {\r
-        Properties p = new Properties();\r
-        if (propText != null) {\r
-            p.load(new ByteArrayInputStream(propText.replace(';', '\n').\r
-                                            getBytes()));\r
-        }\r
-        return p;\r
-    }\r
-\r
-    protected static class DataSourceHandler implements InvocationHandler {\r
-        protected org.apache.tomcat.jdbc.pool.DataSourceProxy datasource = null;\r
-        protected static HashMap<Method,Method> methods = new HashMap<Method,Method>();\r
-        public DataSourceHandler(org.apache.tomcat.jdbc.pool.DataSourceProxy ds) {\r
-            this.datasource = ds;\r
-        }\r
-\r
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-            Method m = methods.get(method);\r
-            if (m==null) {\r
-                m = datasource.getClass().getMethod(method.getName(), method.getParameterTypes());\r
-                methods.put(method, m);\r
-            }\r
-            return m.invoke(datasource, args);\r
-        }\r
-\r
-    }\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java b/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
deleted file mode 100644 (file)
index 878585c..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-import java.io.PrintWriter;\r
-import java.sql.Connection;\r
-import java.sql.SQLException;\r
-import java.util.Iterator;\r
-\r
-import org.apache.juli.logging.Log;\r
-import org.apache.juli.logging.LogFactory;\r
-\r
-/**\r
- *\r
- * <p>Title: Uber Pool</p>\r
- *\r
- * <p>Description: A simple, yet efficient and powerful connection pool</p>\r
- *\r
- * <p>Copyright: Copyright (c) 2008 Filip Hanik</p>\r
- *\r
- * <p> </p>\r
- *\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-\r
-public class DataSourceProxy  {\r
-    protected static Log log = LogFactory.getLog(DataSourceProxy.class);\r
-    \r
-    protected Driver driver;\r
-    protected PoolProperties poolProperties = new PoolProperties();\r
-\r
-    public DataSourceProxy() {\r
-    }\r
-\r
-\r
-    public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
-        // we are not a wrapper of anything\r
-        return false;\r
-    }\r
-\r
-\r
-    public <T> T unwrap(Class<T> iface) throws SQLException {\r
-        //we can't unwrap anything\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public Connection getConnection(String username, String password) throws SQLException {\r
-        return getConnection();\r
-    }\r
-\r
-    public PoolProperties getPoolProperties() {\r
-        return poolProperties;\r
-    }\r
-\r
-    /**\r
-     * Sets up the connection pool, by creating a pooling driver.\r
-     * @return Driver\r
-     * @throws SQLException\r
-     */\r
-    public synchronized Driver createDriver() throws SQLException {\r
-        if (driver != null) {\r
-            return driver;\r
-        } else {\r
-            driver = new org.apache.tomcat.jdbc.pool.Driver(getPoolProperties());\r
-            return driver;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-\r
-    public Connection getConnection() throws SQLException {\r
-        if (driver == null)\r
-            driver = createDriver();\r
-        return driver.connect(poolProperties.getPoolName(), null);\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public PooledConnection getPooledConnection() throws SQLException {\r
-        return (PooledConnection) getConnection();\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public PooledConnection getPooledConnection(String username,\r
-                                                String password) throws SQLException {\r
-        return (PooledConnection) getConnection();\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public PrintWriter getLogWriter() throws SQLException {\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public void setLogWriter(PrintWriter out) throws SQLException {\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public int getLoginTimeout() {\r
-        if (poolProperties == null) {\r
-            return 0;\r
-        } else {\r
-            return poolProperties.getMaxWait() / 1000;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public void setLoginTimeout(int i) {\r
-        if (poolProperties == null) {\r
-            return;\r
-        } else {\r
-            poolProperties.setMaxWait(1000 * i);\r
-        }\r
-\r
-    }\r
-\r
-\r
-    public void close() {\r
-        close(false);\r
-    }\r
-    public void close(boolean all) {\r
-        try {\r
-            if (driver != null) {\r
-                Driver d = driver;\r
-                driver = null;\r
-                d.closePool(poolProperties.getPoolName(), all);\r
-            }\r
-        }catch (Exception x) {\r
-            x.printStackTrace();\r
-        }\r
-    }\r
-\r
-    protected void finalize() throws Throwable {\r
-        //terminate the pool?\r
-        close(true);\r
-    }\r
-\r
-    public int getPoolSize() throws SQLException{\r
-        if (driver == null)\r
-            driver = createDriver();\r
-        return driver.getPool(getPoolProperties().getPoolName()).getSize();\r
-    }\r
-\r
-   public String toString() {\r
-        return super.toString()+"{"+getPoolProperties()+"}";\r
-    }\r
-\r
-/*-----------------------------------------------------------------------*/\r
-//      PROPERTIES WHEN NOT USED WITH FACTORY\r
-/*------------------------------------------------------------------------*/\r
-    public void setPoolProperties(PoolProperties poolProperties) {\r
-        this.poolProperties = poolProperties;\r
-    }\r
-\r
-    public void setDriverClassName(String driverClassName) {\r
-        this.poolProperties.setDriverClassName(driverClassName);\r
-    }\r
-\r
-    public void setInitialSize(int initialSize) {\r
-        this.poolProperties.setInitialSize(initialSize);\r
-    }\r
-\r
-    public void setInitSQL(String initSQL) {\r
-        this.poolProperties.setInitSQL(initSQL);\r
-    }\r
-\r
-    public void setLogAbandoned(boolean logAbandoned) {\r
-        this.poolProperties.setLogAbandoned(logAbandoned);\r
-    }\r
-\r
-    public void setMaxActive(int maxActive) {\r
-        this.poolProperties.setMaxIdle(maxActive);\r
-    }\r
-\r
-    public void setMaxIdle(int maxIdle) {\r
-        this.poolProperties.setMaxIdle(maxIdle);\r
-    }\r
-\r
-    public void setMaxWait(int maxWait) {\r
-        this.poolProperties.setMaxWait(maxWait);\r
-    }\r
-\r
-    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {\r
-        this.poolProperties.setMinEvictableIdleTimeMillis(\r
-            minEvictableIdleTimeMillis);\r
-    }\r
-\r
-    public void setMinIdle(int minIdle) {\r
-        this.setMinIdle(minIdle);\r
-    }\r
-\r
-    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {\r
-        this.poolProperties.setNumTestsPerEvictionRun(numTestsPerEvictionRun);\r
-    }\r
-\r
-    public void setPassword(String password) {\r
-        this.poolProperties.setPassword(password);\r
-        this.poolProperties.getDbProperties().setProperty("password",this.poolProperties.getPassword());\r
-    }\r
-\r
-    public void setRemoveAbandoned(boolean removeAbandoned) {\r
-        this.poolProperties.setRemoveAbandoned(removeAbandoned);\r
-    }\r
-\r
-    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {\r
-        this.poolProperties.setRemoveAbandonedTimeout(removeAbandonedTimeout);\r
-    }\r
-\r
-    public void setTestOnBorrow(boolean testOnBorrow) {\r
-        this.poolProperties.setTestOnBorrow(testOnBorrow);\r
-    }\r
-\r
-    public void setTestOnConnect(boolean testOnConnect) {\r
-        this.poolProperties.setTestOnConnect(testOnConnect);\r
-    }\r
-\r
-    public void setTestOnReturn(boolean testOnReturn) {\r
-        this.poolProperties.setTestOnReturn(testOnReturn);\r
-    }\r
-\r
-    public void setTestWhileIdle(boolean testWhileIdle) {\r
-        this.poolProperties.setTestWhileIdle(testWhileIdle);\r
-    }\r
-\r
-    public void setTimeBetweenEvictionRunsMillis(int\r
-                                                 timeBetweenEvictionRunsMillis) {\r
-        this.poolProperties.setTimeBetweenEvictionRunsMillis(\r
-            timeBetweenEvictionRunsMillis);\r
-    }\r
-\r
-    public void setUrl(String url) {\r
-        this.poolProperties.setUrl(url);\r
-    }\r
-\r
-    public void setUsername(String username) {\r
-        this.poolProperties.setUsername(username);\r
-        this.poolProperties.getDbProperties().setProperty("user",getPoolProperties().getUsername());\r
-    }\r
-\r
-    public void setValidationInterval(long validationInterval) {\r
-        this.poolProperties.setValidationInterval(validationInterval);\r
-    }\r
-\r
-    public void setValidationQuery(String validationQuery) {\r
-        this.poolProperties.setValidationQuery(validationQuery);\r
-    }\r
-\r
-    public void setJdbcInterceptors(String interceptors) {\r
-        this.getPoolProperties().setJdbcInterceptors(interceptors);\r
-    }\r
-\r
-    public void setJmxEnabled(boolean enabled) {\r
-        this.getPoolProperties().setJmxEnabled(enabled);\r
-    }\r
-    \r
-    public void setConnectionProperties(String properties) {\r
-        try {\r
-            java.util.Properties prop = DataSourceFactory.getProperties(properties);\r
-            Iterator i = prop.keySet().iterator();\r
-            while (i.hasNext()) {\r
-                String key = (String)i.next();\r
-                String value = prop.getProperty(key);\r
-                getPoolProperties().getDbProperties().setProperty(key, value);\r
-            }\r
-            \r
-        }catch (Exception x) {\r
-            log.error("Unable to parse connection properties.", x);\r
-            throw new RuntimeException(x);\r
-        }\r
-    }\r
-\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/Driver.java b/java/org/apache/tomcat/jdbc/pool/Driver.java
deleted file mode 100644 (file)
index 9e03825..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-\r
-import java.sql.Connection;\r
-import java.sql.DriverPropertyInfo;\r
-import java.sql.SQLException;\r
-import java.util.HashMap;\r
-import java.util.Properties;\r
-\r
-import org.apache.juli.logging.Log;\r
-import org.apache.juli.logging.LogFactory;\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class Driver implements java.sql.Driver {\r
-\r
-    protected static Log log = LogFactory.getLog(Driver.class);\r
-\r
-    protected static HashMap pooltable = new HashMap(11);\r
-\r
-    public Driver() throws SQLException {\r
-    }\r
-\r
-    public Driver(PoolProperties properties) throws SQLException {\r
-        init(properties);\r
-    } //Driver\r
-\r
-    public void init(PoolProperties properties) throws SQLException {\r
-        if (pooltable.get(properties.getPoolName()) != null)\r
-            throw new SQLException("Pool identified by:" + properties.getPoolName() + " already exists.");\r
-        ConnectionPool pool = new ConnectionPool(properties);\r
-        pooltable.put(properties.getPoolName(), pool);\r
-    }\r
-\r
-    public void closePool(String url, boolean all) throws SQLException {\r
-        ConnectionPool pool = (ConnectionPool) pooltable.get(url);\r
-        if (pool == null) {\r
-            throw new SQLException("No connection pool established for URL:" + url);\r
-        } else {\r
-            pool.close(all);\r
-        }\r
-        pooltable.remove(url);\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public Connection connect(String url, Properties info) throws SQLException {\r
-        ConnectionPool pool = (ConnectionPool) pooltable.get(url);\r
-        if (pool == null) {\r
-            throw new SQLException("No connection pool established for URL:" + url);\r
-        } else {\r
-            try {\r
-                return pool.getConnection();\r
-            } catch (SQLException forward) {\r
-                throw forward;\r
-            } catch (Exception e) {\r
-                throw new SQLException("Unknow pool exception:" + ConnectionPool.getStackTrace(e));\r
-            } //catch\r
-        } //end if\r
-    } //connect\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public boolean acceptsURL(String url) throws SQLException {\r
-        /* check if the driver has a connection pool with that name */\r
-        return (pooltable.get(url) != null ? true : false);\r
-    } //acceptsUrl\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws\r
-        SQLException {\r
-        return new DriverPropertyInfo[0];\r
-    } //getPropertyInfo\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public int getMajorVersion() {\r
-        return 1;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public int getMinorVersion() {\r
-        return 0;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public boolean jdbcCompliant() {\r
-        return true;\r
-    }\r
-\r
-    public ConnectionPool getPool(String url) throws SQLException {\r
-        return (ConnectionPool) pooltable.get(url);\r
-    }\r
-\r
-} //class\r
diff --git a/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java b/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
deleted file mode 100644 (file)
index 67d1086..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-import java.lang.reflect.InvocationHandler;\r
-import java.lang.reflect.Method;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public abstract class JdbcInterceptor implements InvocationHandler {\r
-    public  static final String CLOSE_VAL = "close";\r
-\r
-    private JdbcInterceptor next = null;\r
-\r
-    public JdbcInterceptor() {\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-        if (getNext()!=null) return getNext().invoke(this,method,args);\r
-        else throw new NullPointerException();\r
-    }\r
-\r
-    public JdbcInterceptor getNext() {\r
-        return next;\r
-    }\r
-\r
-    public void setNext(JdbcInterceptor next) {\r
-        this.next = next;\r
-    }\r
-\r
-    public abstract void reset(ConnectionPool parent, PooledConnection con);\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/PoolProperties.java b/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
deleted file mode 100644 (file)
index 6f94d36..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.Properties;\r
-/**\r
- * @author Filip Hanik\r
- *\r
- */\r
-public class PoolProperties {\r
-    protected static volatile int poolCounter = 1;\r
-    protected Properties dbProperties = new Properties();\r
-    protected String url = null;\r
-    protected String driverClassName = null;\r
-    protected Boolean defaultAutoCommit = null;\r
-    protected Boolean defaultReadOnly = null;\r
-    protected int defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;\r
-    protected String defaultCatalog = null;\r
-    protected String connectionProperties;\r
-    protected int initialSize = 10;\r
-    protected int maxActive = 100;\r
-    protected int maxIdle = maxActive;\r
-    protected int minIdle = initialSize;\r
-    protected int maxWait = 30000;\r
-    protected String validationQuery;\r
-    protected boolean testOnBorrow = false;\r
-    protected boolean testOnReturn = false;\r
-    protected boolean testWhileIdle = false;\r
-    protected int timeBetweenEvictionRunsMillis = 5000;\r
-    protected int numTestsPerEvictionRun;\r
-    protected int minEvictableIdleTimeMillis = 60000;\r
-    protected boolean accessToUnderlyingConnectionAllowed;\r
-    protected boolean removeAbandoned = false;\r
-    protected int removeAbandonedTimeout = 60;\r
-    protected boolean logAbandoned = false;\r
-    protected int loginTimeout = 10000;\r
-    protected String name = "Filip Connection Pool["+(poolCounter++)+"]";\r
-    protected String password;\r
-    protected String username;\r
-    protected long validationInterval = 30000;\r
-    protected boolean jmxEnabled = true;\r
-    protected String initSQL;\r
-    protected boolean testOnConnect =false;\r
-    private String jdbcInterceptors=null;\r
-\r
-    public boolean isAccessToUnderlyingConnectionAllowed() {\r
-        return accessToUnderlyingConnectionAllowed;\r
-    }\r
-\r
-    public String getConnectionProperties() {\r
-        return connectionProperties;\r
-    }\r
-\r
-    public Properties getDbProperties() {\r
-        return dbProperties;\r
-    }\r
-\r
-    public boolean isDefaultAutoCommit() {\r
-        return defaultAutoCommit;\r
-    }\r
-\r
-    public String getDefaultCatalog() {\r
-        return defaultCatalog;\r
-    }\r
-\r
-    public boolean isDefaultReadOnly() {\r
-        return defaultReadOnly;\r
-    }\r
-\r
-    public int getDefaultTransactionIsolation() {\r
-        return defaultTransactionIsolation;\r
-    }\r
-\r
-    public String getDriverClassName() {\r
-        return driverClassName;\r
-    }\r
-\r
-    public int getInitialSize() {\r
-        return initialSize;\r
-    }\r
-\r
-    public boolean isLogAbandoned() {\r
-        return logAbandoned;\r
-    }\r
-\r
-    public int getLoginTimeout() {\r
-        return loginTimeout;\r
-    }\r
-\r
-    public int getMaxActive() {\r
-        return maxActive;\r
-    }\r
-\r
-    public int getMaxIdle() {\r
-        return maxIdle;\r
-    }\r
-\r
-    public int getMaxWait() {\r
-        return maxWait;\r
-    }\r
-\r
-    public int getMinEvictableIdleTimeMillis() {\r
-        return minEvictableIdleTimeMillis;\r
-    }\r
-\r
-    public int getMinIdle() {\r
-        return minIdle;\r
-    }\r
-\r
-    public String getName() {\r
-        return name;\r
-    }\r
-\r
-    public int getNumTestsPerEvictionRun() {\r
-        return numTestsPerEvictionRun;\r
-    }\r
-\r
-    public String getPassword() {\r
-        return password;\r
-    }\r
-\r
-    public String getPoolName() {\r
-        return getName();\r
-    }\r
-\r
-    public boolean isRemoveAbandoned() {\r
-        return removeAbandoned;\r
-    }\r
-\r
-    public int getRemoveAbandonedTimeout() {\r
-        return removeAbandonedTimeout;\r
-    }\r
-\r
-    public boolean isTestOnBorrow() {\r
-        return testOnBorrow;\r
-    }\r
-\r
-    public boolean isTestOnReturn() {\r
-        return testOnReturn;\r
-    }\r
-\r
-    public boolean isTestWhileIdle() {\r
-        return testWhileIdle;\r
-    }\r
-\r
-    public int getTimeBetweenEvictionRunsMillis() {\r
-        return timeBetweenEvictionRunsMillis;\r
-    }\r
-\r
-    public String getUrl() {\r
-        return url;\r
-    }\r
-\r
-    public String getUsername() {\r
-        return username;\r
-    }\r
-\r
-    public String getValidationQuery() {\r
-        return validationQuery;\r
-    }\r
-\r
-    public long getValidationInterval() {\r
-        return validationInterval;\r
-    }\r
-\r
-    public String getInitSQL() {\r
-        return initSQL;\r
-    }\r
-\r
-    public boolean isTestOnConnect() {\r
-        return testOnConnect;\r
-    }\r
-\r
-    public String getJdbcInterceptors() {\r
-        return jdbcInterceptors;\r
-    }\r
-\r
-    public String[] getJdbcInterceptorsAsArray() {\r
-        if (jdbcInterceptors==null) return new String[0];\r
-        else {\r
-            return jdbcInterceptors.split(";");\r
-        }\r
-    }\r
-\r
-    public void setAccessToUnderlyingConnectionAllowed(boolean\r
-        accessToUnderlyingConnectionAllowed) {\r
-        this.accessToUnderlyingConnectionAllowed =\r
-            accessToUnderlyingConnectionAllowed;\r
-    }\r
-\r
-    public void setConnectionProperties(String connectionProperties) {\r
-        this.connectionProperties = connectionProperties;\r
-    }\r
-\r
-    public void setDbProperties(Properties dbProperties) {\r
-        this.dbProperties = dbProperties;\r
-    }\r
-\r
-    public void setDefaultAutoCommit(Boolean defaultAutoCommit) {\r
-        this.defaultAutoCommit = defaultAutoCommit;\r
-    }\r
-\r
-    public void setDefaultCatalog(String defaultCatalog) {\r
-        this.defaultCatalog = defaultCatalog;\r
-    }\r
-\r
-    public void setDefaultReadOnly(Boolean defaultReadOnly) {\r
-        this.defaultReadOnly = defaultReadOnly;\r
-    }\r
-\r
-    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {\r
-        this.defaultTransactionIsolation = defaultTransactionIsolation;\r
-    }\r
-\r
-    public void setDriverClassName(String driverClassName) {\r
-        this.driverClassName = driverClassName;\r
-    }\r
-\r
-    public void setInitialSize(int initialSize) {\r
-        this.initialSize = initialSize;\r
-    }\r
-\r
-    public void setLogAbandoned(boolean logAbandoned) {\r
-        this.logAbandoned = logAbandoned;\r
-    }\r
-\r
-    public void setLoginTimeout(int loginTimeout) {\r
-        this.loginTimeout = loginTimeout;\r
-    }\r
-\r
-    public void setMaxActive(int maxActive) {\r
-        this.maxActive = maxActive;\r
-    }\r
-\r
-    public void setMaxIdle(int maxIdle) {\r
-        this.maxIdle = maxIdle;\r
-    }\r
-\r
-    public void setMaxWait(int maxWait) {\r
-        this.maxWait = maxWait;\r
-    }\r
-\r
-    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {\r
-        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;\r
-    }\r
-\r
-    public void setMinIdle(int minIdle) {\r
-        this.minIdle = minIdle;\r
-    }\r
-\r
-    public void setName(String name) {\r
-        this.name = name;\r
-    }\r
-\r
-    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {\r
-        this.numTestsPerEvictionRun = numTestsPerEvictionRun;\r
-    }\r
-\r
-    public void setPassword(String password) {\r
-        this.password = password;\r
-    }\r
-\r
-    public void setRemoveAbandoned(boolean removeAbandoned) {\r
-        this.removeAbandoned = removeAbandoned;\r
-    }\r
-\r
-    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {\r
-        this.removeAbandonedTimeout = removeAbandonedTimeout;\r
-    }\r
-\r
-    public void setTestOnBorrow(boolean testOnBorrow) {\r
-        this.testOnBorrow = testOnBorrow;\r
-    }\r
-\r
-    public void setTestWhileIdle(boolean testWhileIdle) {\r
-        this.testWhileIdle = testWhileIdle;\r
-    }\r
-\r
-    public void setTestOnReturn(boolean testOnReturn) {\r
-        this.testOnReturn = testOnReturn;\r
-    }\r
-\r
-    public void setTimeBetweenEvictionRunsMillis(int\r
-                                                 timeBetweenEvictionRunsMillis) {\r
-        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;\r
-    }\r
-\r
-    public void setUrl(String url) {\r
-        this.url = url;\r
-    }\r
-\r
-    public void setUsername(String username) {\r
-        this.username = username;\r
-    }\r
-\r
-    public void setValidationInterval(long validationInterval) {\r
-        this.validationInterval = validationInterval;\r
-    }\r
-\r
-    public void setValidationQuery(String validationQuery) {\r
-        this.validationQuery = validationQuery;\r
-    }\r
-\r
-    public void setInitSQL(String initSQL) {\r
-        this.initSQL = initSQL;\r
-    }\r
-\r
-    public void setTestOnConnect(boolean testOnConnect) {\r
-        this.testOnConnect = testOnConnect;\r
-    }\r
-\r
-    public void setJdbcInterceptors(String jdbcInterceptors) {\r
-        this.jdbcInterceptors = jdbcInterceptors;\r
-    }\r
-\r
-    public String toString() {\r
-        StringBuffer buf = new StringBuffer("ConnectionPool[");\r
-        try {\r
-            String[] fields = DataSourceFactory.ALL_PROPERTIES;\r
-            for (int i=0; i<fields.length; i++) {\r
-                final String[] prefix = new String[] {"get","is"};\r
-                for (int j=0; j<prefix.length; j++) {\r
-\r
-                    String name = prefix[j] + fields[i].substring(0, 1).toUpperCase() +\r
-                                  fields[i].substring(1);\r
-                    Method m = null;\r
-                    try {\r
-                        m = getClass().getMethod(name);\r
-                    }catch (NoSuchMethodException nm) {\r
-                        continue;\r
-                    }\r
-                    buf.append(fields[i]);\r
-                    buf.append("=");\r
-                    buf.append(m.invoke(this, new Object[0]));\r
-                    buf.append("; ");\r
-                    break;\r
-                }\r
-            }\r
-        }catch (Exception x) {\r
-            //shouldn;t happen\r
-            x.printStackTrace();\r
-        }\r
-        return buf.toString();\r
-    }\r
-\r
-    public static int getPoolCounter() {\r
-        return poolCounter;\r
-    }\r
-\r
-    public boolean isJmxEnabled() {\r
-        return jmxEnabled;\r
-    }\r
-\r
-    public void setJmxEnabled(boolean jmxEnabled) {\r
-        this.jmxEnabled = jmxEnabled;\r
-    }\r
-\r
-    public Boolean getDefaultAutoCommit() {\r
-        return defaultAutoCommit;\r
-    }\r
-\r
-    public Boolean getDefaultReadOnly() {\r
-        return defaultReadOnly;\r
-    }\r
-    \r
-    public boolean isPoolSweeperEnabled() {\r
-        boolean result = getTimeBetweenEvictionRunsMillis()>0;\r
-        result = result && (isRemoveAbandoned() && getRemoveAbandonedTimeout()>0);\r
-        result = result && (isTestWhileIdle() && getValidationQuery()!=null);\r
-        return result;\r
-    }\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/PooledConnection.java b/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
deleted file mode 100644 (file)
index 7998391..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-\r
-import java.lang.ref.WeakReference;\r
-import java.sql.SQLException;\r
-import java.sql.Statement;\r
-import java.util.concurrent.locks.ReentrantReadWriteLock;\r
-\r
-import org.apache.juli.logging.Log;\r
-import org.apache.juli.logging.LogFactory;\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class PooledConnection {\r
-\r
-    public static final int VALIDATE_BORROW = 1;\r
-    public static final int VALIDATE_RETURN = 2;\r
-    public static final int VALIDATE_IDLE = 3;\r
-    public static final int VALIDATE_INIT = 4;\r
-\r
-    protected static Log log = LogFactory.getLog(PooledConnection.class);\r
-    protected static volatile int counter = 1;\r
-\r
-    protected PoolProperties poolProperties;\r
-    protected java.sql.Connection connection;\r
-    protected String abandonTrace = null;\r
-    protected long timestamp;\r
-    protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);\r
-    protected boolean discarded = false;\r
-    protected long lastValidated = System.currentTimeMillis();\r
-    protected int instanceCount = 0;\r
-    protected ConnectionPool parent;\r
-\r
-    protected WeakReference<JdbcInterceptor> handler = null;\r
-\r
-    public PooledConnection(PoolProperties prop, ConnectionPool parent) throws SQLException {\r
-        instanceCount = counter++;\r
-        poolProperties = prop;\r
-        this.parent = parent;\r
-    }\r
-\r
-    protected void connect() throws SQLException {\r
-        if (connection != null) {\r
-            try {\r
-                this.disconnect();\r
-            } catch (Exception x) {\r
-                log.error("Unable to disconnect previous connection.", x);\r
-            } //catch\r
-        } //end if\r
-        java.sql.Driver driver = null;\r
-        try {\r
-            driver = (java.sql.Driver) Class.forName(poolProperties.getDriverClassName(),\r
-                                                     true, PooledConnection.class.getClassLoader()).newInstance();\r
-        } catch (java.lang.Exception cn) {\r
-            log.error("Unable to instantiate JDBC driver.", cn);\r
-            throw new SQLException(cn.getMessage());\r
-        }\r
-        String driverURL = poolProperties.getUrl();\r
-        String usr = poolProperties.getUsername();\r
-        String pwd = poolProperties.getPassword();\r
-        poolProperties.getDbProperties().setProperty("user", usr);\r
-        poolProperties.getDbProperties().setProperty("password", pwd);\r
-        connection = driver.connect(driverURL, poolProperties.getDbProperties());\r
-        //set up the default state\r
-        if (poolProperties.getDefaultReadOnly()!=null) connection.setReadOnly(poolProperties.getDefaultReadOnly().booleanValue());\r
-        if (poolProperties.getDefaultAutoCommit()!=null) connection.setAutoCommit(poolProperties.getDefaultAutoCommit().booleanValue());\r
-        if (poolProperties.getDefaultCatalog()!=null) connection.setCatalog(poolProperties.getDefaultCatalog());\r
-        if (poolProperties.getDefaultTransactionIsolation()!=DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION) connection.setTransactionIsolation(poolProperties.getDefaultTransactionIsolation());\r
-        \r
-        this.discarded = false;\r
-    }\r
-\r
-    protected void reconnect() throws SQLException {\r
-        this.disconnect();\r
-        this.connect();\r
-    } //reconnect\r
-\r
-    protected synchronized void disconnect() throws SQLException {\r
-        if (isDiscarded()) {\r
-            return;\r
-        }\r
-        setDiscarded(true);\r
-        if (connection != null) {\r
-            connection.close();\r
-        }\r
-        connection = null;\r
-        parent.finalize(this);\r
-    }\r
-\r
-\r
-//============================================================================\r
-//             com.filip.util.IPoolObject methods\r
-//============================================================================\r
-\r
-    public long getAbandonTimeout() {\r
-        if (poolProperties.getRemoveAbandonedTimeout() <= 0) {\r
-            return Long.MAX_VALUE;\r
-        } else {\r
-            return poolProperties.getRemoveAbandonedTimeout()*1000;\r
-        } //end if\r
-    }\r
-\r
-    public boolean abandon() {\r
-        try {\r
-            disconnect();\r
-        } catch (SQLException x) {\r
-            log.error("", x);\r
-        } //catch\r
-        return false;\r
-    }\r
-\r
-    protected boolean doValidate(int action) {\r
-        if (action == PooledConnection.VALIDATE_BORROW &&\r
-            poolProperties.isTestOnBorrow())\r
-            return true;\r
-        else if (action == PooledConnection.VALIDATE_RETURN &&\r
-                 poolProperties.isTestOnReturn())\r
-            return true;\r
-        else if (action == PooledConnection.VALIDATE_IDLE &&\r
-                 poolProperties.isTestWhileIdle())\r
-            return true;\r
-        else if (action == PooledConnection.VALIDATE_INIT &&\r
-                 poolProperties.isTestOnConnect())\r
-            return true;\r
-        else if (action == PooledConnection.VALIDATE_INIT &&\r
-                 poolProperties.getInitSQL()!=null)\r
-           return true;\r
-        else\r
-            return false;\r
-    }\r
-\r
-    /**Returns true if the object is still valid. if not\r
-     * the pool will call the getExpiredAction() and follow up with one\r
-     * of the four expired methods\r
-     */\r
-    public boolean validate(int validateAction) {\r
-        return validate(validateAction,null);\r
-    }\r
-\r
-    public boolean validate(int validateAction,String sql) {\r
-        if (!doValidate(validateAction)) {\r
-            //no validation required, no init sql and props not set\r
-            return true;\r
-        }\r
-\r
-        String query = (VALIDATE_INIT==validateAction && (poolProperties.getInitSQL()!=null))?poolProperties.getInitSQL():sql;\r
-\r
-        if (query==null) query = poolProperties.getValidationQuery();\r
-\r
-        if (query == null) {\r
-            //no validation possible\r
-            return true;\r
-        }\r
-        long now = System.currentTimeMillis();\r
-        if (this.poolProperties.getValidationInterval() > 0 &&\r
-            (now - this.lastValidated) <\r
-            this.poolProperties.getValidationInterval()) {\r
-            return true;\r
-        }\r
-        try {\r
-            Statement stmt = connection.createStatement();\r
-            boolean exec = stmt.execute(query);\r
-            stmt.close();\r
-            this.lastValidated = now;\r
-            return true;\r
-        } catch (Exception ignore) {\r
-            if (log.isDebugEnabled())\r
-                log.debug("Unable to validate object:",ignore);\r
-        }\r
-        return false;\r
-    } //validate\r
-\r
-    /**\r
-     * The time limit for how long the object\r
-     * can remain unused before it is released\r
-     */\r
-    public long getReleaseTime() {\r
-        return this.poolProperties.getMinEvictableIdleTimeMillis();\r
-    }\r
-\r
-    /**\r
-     * This method is called if (Now - timeCheckedIn > getReleaseTime())\r
-     */\r
-    public void release() {\r
-        try {\r
-            disconnect();\r
-        } catch (SQLException x) {\r
-            //TODO\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * The pool will set the stack trace when it is check out and\r
-     * checked in\r
-     */\r
-\r
-    public void setStackTrace(String trace) {\r
-        abandonTrace = trace;\r
-    }\r
-\r
-    public String getStackTrace() {\r
-        return abandonTrace;\r
-    }\r
-\r
-    public void setTimestamp(long timestamp) {\r
-        this.timestamp = timestamp;\r
-    }\r
-\r
-    public void setDiscarded(boolean discarded) {\r
-        if (this.discarded && !discarded) throw new IllegalStateException("Unable to change the state once the connection has been discarded");\r
-        this.discarded = discarded;\r
-    }\r
-\r
-    public void setLastValidated(long lastValidated) {\r
-        this.lastValidated = lastValidated;\r
-    }\r
-\r
-    public void setPoolProperties(PoolProperties poolProperties) {\r
-        this.poolProperties = poolProperties;\r
-    }\r
-\r
-    public long getTimestamp() {\r
-        return timestamp;\r
-    }\r
-\r
-    public boolean isDiscarded() {\r
-        return discarded;\r
-    }\r
-\r
-    public long getLastValidated() {\r
-        return lastValidated;\r
-    }\r
-\r
-    public PoolProperties getPoolProperties() {\r
-        return poolProperties;\r
-    }\r
-\r
-    public void lock() {\r
-        if (this.poolProperties.isPoolSweeperEnabled()) {\r
-            //optimized, only use a lock when there is concurrency\r
-            lock.writeLock().lock();\r
-        }\r
-    }\r
-\r
-    public void unlock() {\r
-        if (this.poolProperties.isPoolSweeperEnabled()) {\r
-          //optimized, only use a lock when there is concurrency\r
-            lock.writeLock().unlock();\r
-        }\r
-    }\r
-\r
-    public java.sql.Connection getConnection() {\r
-        return this.connection;\r
-    }\r
-\r
-    public JdbcInterceptor getHandler() {\r
-        return (handler!=null)?handler.get():null;\r
-    }\r
-\r
-    public void setHandler(JdbcInterceptor handler) {\r
-        if (handler==null) {\r
-            if (this.handler!=null) this.handler.clear();\r
-        } else if (this.handler==null) {\r
-            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
-        } else if (this.handler.get()==null) {\r
-            this.handler.clear();\r
-            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
-        } else if (this.handler.get()!=handler) {\r
-            this.handler.clear();\r
-            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
-        }\r
-    }\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java b/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java
deleted file mode 100644 (file)
index 9a66536..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool;\r
-\r
-import java.lang.reflect.Method;\r
-import java.sql.Connection;\r
-import java.sql.SQLException;\r
-/**\r
- * @author Filip Hanik\r
- */\r
-public class ProxyConnection extends JdbcInterceptor {\r
-\r
-    protected PooledConnection connection = null;\r
-\r
-    protected ConnectionPool pool = null;\r
-\r
-    public PooledConnection getConnection() {\r
-        return connection;\r
-    }\r
-\r
-    public void setConnection(PooledConnection connection) {\r
-        this.connection = connection;\r
-    }\r
-\r
-    public ConnectionPool getPool() {\r
-        return pool;\r
-    }\r
-\r
-    public void setPool(ConnectionPool pool) {\r
-        this.pool = pool;\r
-    }\r
-\r
-    protected ProxyConnection(ConnectionPool parent, PooledConnection con) throws SQLException {\r
-        pool = parent;\r
-        connection = con;\r
-    }\r
-\r
-    public void reset(ConnectionPool parent, PooledConnection con) {\r
-        this.pool = parent;\r
-        this.connection = con;\r
-    }\r
-\r
-    public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
-        return (iface.isInstance(connection.getConnection()));\r
-    }\r
-\r
-\r
-    public Object unwrap(Class iface) throws SQLException {\r
-        if (isWrapperFor(iface)) {\r
-            return connection.getConnection();\r
-        } else {\r
-            throw new SQLException("Not a wrapper of "+iface.getName());\r
-        }\r
-    }\r
-\r
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-        if (isClosed()) throw new SQLException("Connection has already been closed.");\r
-        if (CLOSE_VAL==method.getName()) {\r
-            PooledConnection poolc = this.connection;\r
-            this.connection = null;\r
-            pool.returnConnection(poolc);\r
-            return null;\r
-        }\r
-        return method.invoke(connection.getConnection(),args);\r
-    }\r
-\r
-    public boolean isClosed() {\r
-        return connection==null || connection.isDiscarded();\r
-    }\r
-\r
-    public PooledConnection getDelegateConnection() {\r
-        return connection;\r
-    }\r
-\r
-    public ConnectionPool getParentPool() {\r
-        return pool;\r
-    }\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java b/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java
deleted file mode 100644 (file)
index b30ae01..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool.interceptor;\r
-\r
-import java.lang.reflect.Method;\r
-\r
-import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
-import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
-import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
-import org.apache.tomcat.jdbc.pool.PooledConnection;\r
-\r
-/**\r
- * Interceptor that keep track of connection state to avoid roundtrips to the database\r
- * @author fhanik\r
- *\r
- */\r
-\r
-public class ConnectionState extends JdbcInterceptor  {\r
-\r
-    protected final String[] readState = {"getAutoCommit","getTransactionIsolation","isReadOnly"};\r
-    protected final String[] writeState = {"setAutoCommit","setTransactionIsolation","setReadOnly"};\r
-\r
-    protected Boolean autoCommit = null;\r
-    protected Integer transactionIsolation = null;\r
-    protected Boolean readOnly = null;\r
-\r
-    public void reset(ConnectionPool parent, PooledConnection con) {\r
-        autoCommit = null;\r
-        transactionIsolation = null;\r
-        readOnly = null;\r
-    }\r
-\r
-    @Override\r
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-        String name = method.getName();\r
-        boolean read = false;\r
-        int index = -1;\r
-        for (int i=0; (!read) && i<readState.length; i++) {\r
-            read = name==readState[i];\r
-            if (read) index = i;\r
-        }\r
-        boolean write = false;\r
-        for (int i=0; (!write) && (!read) && i<writeState.length; i++) {\r
-            write = name==writeState[i];\r
-            if (write) index = i;\r
-        }\r
-        Object result = null;\r
-        if (read) {\r
-            switch (index) {\r
-                case 0:{result = autoCommit; break;}\r
-                case 1:{result = transactionIsolation; break;}\r
-                case 2:{result = readOnly; break;}\r
-                default: result = null;\r
-            }\r
-            //return cached result, if we have it\r
-            if (result!=null) return result;\r
-        }\r
-\r
-        result = super.invoke(proxy, method, args);\r
-        if (read || write) {\r
-            switch (index) {\r
-                case 0:{autoCommit = (Boolean) (read?result:args[0]); break;}\r
-                case 1:{transactionIsolation = (Integer)(read?result:args[0]); break;}\r
-                case 2:{readOnly = (Boolean)(read?result:args[0]); break;}\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java b/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
deleted file mode 100644 (file)
index aa3efab..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool.interceptor;\r
-\r
-import java.lang.reflect.InvocationHandler;\r
-import java.lang.reflect.Method;\r
-import java.lang.reflect.Proxy;\r
-import java.sql.CallableStatement;\r
-import java.sql.SQLException;\r
-\r
-import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
-import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
-import org.apache.tomcat.jdbc.pool.PooledConnection;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class SlowQueryReport extends JdbcInterceptor {\r
-    protected final String[] statements = {"createStatement","prepareStatement","prepareCall"};\r
-    protected final String[] executes = {"execute","executeQuery","executeUpdate","executeBatch"};\r
-\r
-    public SlowQueryReport() {\r
-        super();\r
-    }\r
-\r
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-        boolean process = false;\r
-        process = process(statements, method, process);\r
-        if (process) {\r
-            Object statement = super.invoke(proxy,method,args);\r
-            CallableStatement measuredStatement =\r
-                (CallableStatement)Proxy.newProxyInstance(SlowQueryReport.class.getClassLoader(),\r
-                    new Class[] {java.sql.CallableStatement.class,\r
-                                 java.sql.PreparedStatement.class,\r
-                                 java.sql.Statement.class},\r
-                    new StatementProxy(statement, args));\r
-\r
-            return measuredStatement;\r
-        } else {\r
-            return super.invoke(proxy,method,args);\r
-        }\r
-    }\r
-\r
-    protected boolean process(String[] names, Method method, boolean process) {\r
-        for (int i=0; (!process) && i<names.length; i++) {\r
-            process = (method.getName()==names[i]);\r
-        }\r
-        return process;\r
-    }\r
-\r
-    protected class StatementProxy implements InvocationHandler {\r
-        protected Object parent;\r
-        protected Object[] args;\r
-        public StatementProxy(Object parent, Object[] args) {\r
-            this.parent = parent;\r
-            this.args = args;\r
-        }\r
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
-            if (this.parent == null ) throw new SQLException("Statement has been closed.");\r
-            boolean process = false;\r
-            process = process(executes, method, process);\r
-            long start = (process)?System.currentTimeMillis():0;\r
-            //execute the query\r
-            Object result =  method.invoke(parent,args);\r
-            long delta = (process)?(System.currentTimeMillis()-start):0;\r
-            if (delta>10) {\r
-                StringBuffer out = new StringBuffer("\n\tType:");\r
-                out.append(parent.getClass().getName());\r
-                out.append("\n\tCreate/Prepare args:");\r
-                for (int i=0; this.args!=null && i<this.args.length;i++) {\r
-                    out.append(this.args[i]!=null?this.args[i]:"null");\r
-                    out.append("; ");\r
-                }\r
-                out.append("\n\tExecute args:");\r
-                for (int i=0; args!=null && i<args.length;i++) {\r
-                    out.append(args[i]!=null?args[i]:"null");\r
-                    out.append("; ");\r
-                }\r
-                System.out.println("Slow query:"+out+"\nTime to execute:"+(delta)+" ms.");\r
-            }\r
-            if (JdbcInterceptor.CLOSE_VAL==method.getName()) {\r
-                this.parent = null;\r
-                this.args = null;\r
-            }\r
-            return result;\r
-        }\r
-    }\r
-\r
-    public void reset(ConnectionPool parent, PooledConnection con) {\r
-\r
-    }\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java b/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
deleted file mode 100644 (file)
index f8a63ec..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool.jmx;\r
-/**\r
- * @author Filip Hanik\r
- */\r
-import java.util.Properties;\r
-\r
-import javax.management.DynamicMBean;\r
-\r
-import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
-\r
-public class ConnectionPool implements ConnectionPoolMBean  {\r
-    protected org.apache.tomcat.jdbc.pool.ConnectionPool pool = null;\r
-\r
-    public ConnectionPool(org.apache.tomcat.jdbc.pool.ConnectionPool pool) {\r
-        this.pool = pool;\r
-    }\r
-\r
-    public org.apache.tomcat.jdbc.pool.ConnectionPool getPool() {\r
-        return pool;\r
-    }\r
-\r
-    //=================================================================\r
-    //       POOL STATS\r
-    //=================================================================\r
-\r
-    public int getSize() {\r
-        return pool.getSize();\r
-    }\r
-\r
-    public int getIdle() {\r
-        return pool.getIdle();\r
-    }\r
-\r
-    public int getActive() {\r
-        return pool.getActive();\r
-    }\r
-    \r
-    public boolean isPoolSweeperEnabled() {\r
-        return pool.getPoolProperties().isPoolSweeperEnabled();\r
-    }\r
-\r
-    //=================================================================\r
-    //       POOL OPERATIONS\r
-    //=================================================================\r
-    public void checkIdle() {\r
-        pool.checkIdle();\r
-    }\r
-\r
-    public void checkAbandoned() {\r
-        pool.checkAbandoned();\r
-    }\r
-\r
-    public void testIdle() {\r
-        pool.testAllIdle();\r
-    }\r
-    //=================================================================\r
-    //       POOL PROPERTIES\r
-    //=================================================================\r
-    public Properties getDbProperties() {\r
-        return pool.getPoolProperties().getDbProperties();\r
-    }\r
-    public String getUrl() {\r
-        return pool.getPoolProperties().getUrl();\r
-    }\r
-    public String getDriverClassName() {\r
-        return pool.getPoolProperties().getDriverClassName();\r
-    }\r
-    public boolean isDefaultAutoCommit() {\r
-        return pool.getPoolProperties().isDefaultAutoCommit();\r
-    }\r
-    public boolean isDefaultReadOnly() {\r
-        return pool.getPoolProperties().isDefaultReadOnly();\r
-    }\r
-    public int getDefaultTransactionIsolation() {\r
-        return pool.getPoolProperties().getDefaultTransactionIsolation();\r
-    }\r
-    public String getConnectionProperties() {\r
-        return pool.getPoolProperties().getConnectionProperties();\r
-    }\r
-    public String getDefaultCatalog() {\r
-        return pool.getPoolProperties().getDefaultCatalog();\r
-    }\r
-    public int getInitialSize() {\r
-        return pool.getPoolProperties().getInitialSize();\r
-    }\r
-    public int getMaxActive() {\r
-        return pool.getPoolProperties().getMaxActive();\r
-    }\r
-    public int getMaxIdle() {\r
-        return pool.getPoolProperties().getMaxIdle();\r
-    }\r
-    public int getMinIdle() {\r
-        return pool.getPoolProperties().getMinIdle();\r
-    }\r
-    public int getMaxWait() {\r
-        return pool.getPoolProperties().getMaxWait();\r
-    }\r
-    public String getValidationQuery() {\r
-        return pool.getPoolProperties().getValidationQuery();\r
-    }\r
-    public boolean isTestOnBorrow() {\r
-        return pool.getPoolProperties().isTestOnBorrow();\r
-    }\r
-    public boolean isTestOnReturn() {\r
-        return pool.getPoolProperties().isTestOnReturn();\r
-    }\r
-    public boolean isTestWhileIdle() {\r
-        return pool.getPoolProperties().isTestWhileIdle();\r
-    }\r
-    public int getTimeBetweenEvictionRunsMillis() {\r
-        return pool.getPoolProperties().getTimeBetweenEvictionRunsMillis();\r
-    }\r
-    public int getNumTestsPerEvictionRun() {\r
-        return pool.getPoolProperties().getNumTestsPerEvictionRun();\r
-    }\r
-    public int getMinEvictableIdleTimeMillis() {\r
-        return pool.getPoolProperties().getMinEvictableIdleTimeMillis();\r
-    }\r
-    public boolean isAccessToUnderlyingConnectionAllowed() {\r
-        return pool.getPoolProperties().isAccessToUnderlyingConnectionAllowed();\r
-    }\r
-    public boolean isRemoveAbandoned() {\r
-        return pool.getPoolProperties().isRemoveAbandoned();\r
-    }\r
-    public int getRemoveAbandonedTimeout() {\r
-        return pool.getPoolProperties().getRemoveAbandonedTimeout();\r
-    }\r
-    public boolean isLogAbandoned() {\r
-        return pool.getPoolProperties().isLogAbandoned();\r
-    }\r
-    public int getLoginTimeout() {\r
-        return pool.getPoolProperties().getLoginTimeout();\r
-    }\r
-    public String getName() {\r
-        return pool.getPoolProperties().getName();\r
-    }\r
-    public String getPassword() {\r
-        return pool.getPoolProperties().getPassword();\r
-    }\r
-    public String getUsername() {\r
-        return pool.getPoolProperties().getUsername();\r
-    }\r
-    public long getValidationInterval() {\r
-        return pool.getPoolProperties().getValidationInterval();\r
-    }\r
-    public String getInitSQL() {\r
-        return pool.getPoolProperties().getInitSQL();\r
-    }\r
-    public boolean isTestOnConnect() {\r
-        return pool.getPoolProperties().isTestOnConnect();\r
-    }\r
-    public String getJdbcInterceptors() {\r
-        return pool.getPoolProperties().getJdbcInterceptors();\r
-    }\r
-\r
-}\r
diff --git a/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java b/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
deleted file mode 100644 (file)
index 053fc2d..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.pool.jmx;\r
-\r
-import java.util.Properties;\r
-\r
-import javax.management.DynamicMBean;\r
-\r
-import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
-import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
-\r
-public interface ConnectionPoolMBean  {\r
-\r
-    //=================================================================\r
-    //       POOL STATS\r
-    //=================================================================\r
-\r
-    public int getSize();\r
-\r
-    public int getIdle();\r
-\r
-    public int getActive();\r
-    \r
-    public boolean isPoolSweeperEnabled();\r
-\r
-    //=================================================================\r
-    //       POOL OPERATIONS\r
-    //=================================================================\r
-    public void checkIdle();\r
-\r
-    public void checkAbandoned();\r
-\r
-    public void testIdle();\r
-\r
-    //=================================================================\r
-    //       POOL PROPERTIES\r
-    //=================================================================\r
-    public Properties getDbProperties();\r
-\r
-    public String getUrl();\r
-\r
-    public String getDriverClassName();\r
-\r
-    public boolean isDefaultAutoCommit();\r
-\r
-    public boolean isDefaultReadOnly();\r
-\r
-    public int getDefaultTransactionIsolation();\r
-\r
-    public String getConnectionProperties();\r
-\r
-    public String getDefaultCatalog();\r
-\r
-    public int getInitialSize();\r
-\r
-    public int getMaxActive();\r
-\r
-    public int getMaxIdle();\r
-\r
-    public int getMinIdle();\r
-\r
-    public int getMaxWait();\r
-\r
-    public String getValidationQuery();\r
-\r
-    public boolean isTestOnBorrow();\r
-\r
-    public boolean isTestOnReturn();\r
-\r
-    public boolean isTestWhileIdle();\r
-\r
-    public int getTimeBetweenEvictionRunsMillis();\r
-\r
-    public int getNumTestsPerEvictionRun();\r
-\r
-    public int getMinEvictableIdleTimeMillis();\r
-\r
-    public boolean isAccessToUnderlyingConnectionAllowed();\r
-\r
-    public boolean isRemoveAbandoned();\r
-\r
-    public int getRemoveAbandonedTimeout();\r
-\r
-    public boolean isLogAbandoned();\r
-\r
-    public int getLoginTimeout();\r
-\r
-    public String getName();\r
-\r
-    public String getPassword();\r
-\r
-    public String getUsername();\r
-\r
-    public long getValidationInterval();\r
-\r
-    public String getInitSQL();\r
-\r
-    public boolean isTestOnConnect();\r
-\r
-    public String getJdbcInterceptors();\r
-\r
-}\r
diff --git a/modules/jdbc-pool/build.xml b/modules/jdbc-pool/build.xml
new file mode 100644 (file)
index 0000000..917cb84
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0"?>\r
+<!--\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+  contributor license agreements.  See the NOTICE file distributed with\r
+  this work for additional information regarding copyright ownership.\r
+  The ASF licenses this file to You under the Apache License, Version 2.0\r
+  (the "License"); you may not use this file except in compliance with\r
+  the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+-->\r
+<project name="Tomcat Trunk" default="conpool" basedir="../..">\r
+\r
+\r
+  <!-- ===================== Initialize Property Values =================== -->\r
+\r
+  <!-- See "build.properties.sample" in the top level directory for all     -->\r
+  <!-- property values you must customize for successful building!!!        -->\r
+  <property file="${user.home}/build.properties"/>\r
+  <property file="${basedir}/build.properties"/>\r
+\r
+  <property file="${basedir}/build.properties.default"/>\r
+\r
+  <!-- Project Properties -->\r
+  <property name="name"                  value="Apache Tomcat" />\r
+  <property name="year"                  value="2007" />\r
+  <property name="version.major"         value="6" />\r
+  <property name="version.minor"         value="0" />\r
+  <property name="version.build"         value="0" />\r
+  <property name="version.patch"         value="0" />\r
+  <property name="version"               value="6.0.0-dev" />\r
+  <property name="version.number"        value="${version.major}.${version.minor}.${version.build}.${version.patch}" />\r
+\r
+  <property name="project"               value="apache-tomcat" />\r
+  <property name="final.name"            value="${project}-${version}" />\r
+  <property name="final-src.name"        value="${project}-${version}-src" />\r
+\r
+  <!-- Build Defaults -->\r
+  <property name="tomcat.build"      value="${basedir}/output/build"/>\r
+  <property name="tomcat.classes"    value="${basedir}/output/classes"/>\r
+  <property name="tomcat.dist"       value="${basedir}/output/dist"/>\r
+  <property name="tomcat.extras"     value="${basedir}/output/extras"/>\r
+  <property name="tomcat.deployer"   value="${basedir}/output/deployer"/>\r
+  <property name="tomcat.release"    value="${basedir}/output/release"/>\r
+  <property name="test.failonerror"  value="true"/>\r
+  <property name="test.runner"       value="junit.textui.TestRunner"/>\r
+\r
+  <!-- Can't be lower - jsp uses templates -->\r
+  <property name="compile.source" value="1.5"/>\r
+\r
+  <!-- JAR artifacts -->\r
+  <property name="bootstrap.jar" value="${tomcat.build}/bin/bootstrap.jar"/>\r
+\r
+  <property name="annotations-api.jar" value="${tomcat.build}/lib/annotations-api.jar"/>\r
+  <property name="servlet-api.jar" value="${tomcat.build}/lib/servlet-api.jar"/>\r
+  <property name="jsp-api.jar" value="${tomcat.build}/lib/jsp-api.jar"/>\r
+  <property name="el-api.jar" value="${tomcat.build}/lib/el-api.jar"/>\r
+  <property name="catalina.jar" value="${tomcat.build}/lib/catalina.jar"/>\r
+  <property name="catalina-ant.jar" value="${tomcat.build}/lib/catalina-ant.jar"/>\r
+  <property name="tomcat-coyote.jar" value="${tomcat.build}/lib/tomcat-coyote.jar"/>\r
+\r
+  <property name="jasper.jar" value="${tomcat.build}/lib/jasper.jar"/>\r
+  <property name="jasper-el.jar" value="${tomcat.build}/lib/jasper-el.jar"/>\r
+\r
+  <property name="tomcat-dbcp.home" value="${base.path}/tomcat6-deps/dbcp" />\r
+  <property name="jasper-jdt.home" value="${base.path}/tomcat6-deps/jdt" />\r
+  <property name="tomcat-dbcp.jar" value="${tomcat-dbcp.home}/tomcat-dbcp.jar"/>\r
+  <property name="jasper-jdt.jar" value="${jasper-jdt.home}/jasper-jdt.jar"/>\r
+\r
+  <property name="tomcat-juli.jar" value="${tomcat.extras}/tomcat-juli.jar"/>\r
+  <property name="tomcat-juli-adapters.jar" value="${tomcat.extras}/tomcat-juli-adapters.jar"/>\r
+  <property name="catalina-ws.jar" value="${tomcat.extras}/catalina-ws.jar"/>\r
+\r
+  <property name="cometd-api.jar" value="${tomcat.extras}/cometd-api.jar"/>\r
+  <property name="tomcat-bayeux.jar" value="${tomcat.extras}/tomcat-bayeux.jar"/>\r
+  <property name="cometd.war" value="${tomcat.extras}/cometd.war"/>\r
+  <property name="tomcat-bayeux-samples.jar" value="${tomcat.extras}/tomcat-bayeux-samples.jar"/>\r
+\r
+  <property name="tomcat-jdbc.jar" value="${tomcat.extras}/tomcat-jdbc.jar"/>\r
+\r
+  <property name="catalina-jmx-remote.jar" value="${tomcat.extras}/catalina-jmx-remote.jar"/>\r
+       \r
+  <!-- Classpath -->\r
+  <path id="tomcat.classpath">\r
+    <pathelement location="${tomcat.classes}"/>\r
+  </path>\r
+\r
+  <target name="prepare">\r
+    <mkdir dir="${tomcat.extras}"/>\r
+  </target>\r
+\r
+  <target name="conpool">\r
+    <mkdir dir="${tomcat.extras}"/>\r
+    <path id="tomcat.jdbc.classpath">\r
+      <pathelement path="${tomcat.classpath}"/>\r
+    </path>\r
+\r
+    <!-- compile org.apache.tomcat.jdbc-->\r
+    <javac srcdir="${basedir}/modules/jdbc-pool/java" destdir="${tomcat.classes}"\r
+           debug="${compile.debug}"\r
+           deprecation="${compile.deprecation}"\r
+           source="${compile.source}"\r
+           optimize="${compile.optimize}">\r
+      <classpath refid="tomcat.jdbc.classpath"/>\r
+      <include name="org/apache/tomcat/jdbc/**" />\r
+    </javac>\r
+    \r
+    <!-- connection pool JAR File -->\r
+    <jar jarfile="${tomcat-jdbc.jar}">\r
+      <fileset dir="${tomcat.classes}">\r
+        <include name="org/apache/tomcat/jdbc/**" />\r
+      </fileset>\r
+    </jar>\r
+    <!-- create checksums -->\r
+    <checksum file="${tomcat-jdbc.jar}" forceOverwrite="yes" fileext=".md5" />\r
+  </target>\r
+\r
+  <target name="clean"> \r
+      <delete file="${tomcat-jdbc.jar}"/>\r
+      <delete file="${tomcat-jdbc.jar}.md5"/>\r
+      <delete includeemptydirs="true">\r
+          <fileset dir="${tomcat.classes}">\r
+            <include name="org/apache/tomcat/jdbc/**"/>\r
+          </fileset>\r
+      </delete>\r
+  </target>\r
+       \r
+  <!-- Download and dependency building -->\r
+  <target name="proxyflags">\r
+    <!-- check proxy parameters. -->\r
+    <condition property="useproxy">\r
+      <equals arg1="${proxy.use}" arg2="on" />\r
+    </condition>\r
+  </target>\r
+\r
+  <target name="setproxy" depends="proxyflags" if="useproxy">\r
+    <taskdef name="setproxy"\r
+            classname="org.apache.tools.ant.taskdefs.optional.net.SetProxy" />\r
+    <setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"\r
+              proxyuser="${proxy.user}" proxypassword="${proxy.password}" />\r
+    <echo message="Using ${proxy.host}:${proxy.port} to download ${sourcefile}"/>\r
+  </target>\r
+\r
+  <target name="testexist">\r
+    <echo message="Testing  for ${destfile}"/>\r
+    <available file="${destfile}" property="exist"/>\r
+  </target>\r
+\r
+  <target name="downloadfile" unless="exist" depends="setproxy,testexist">\r
+    <!-- Download extract the file -->\r
+    <mkdir dir="${destdir}" />\r
+    <get src="${sourcefile}" dest="${destfile}" />\r
+  </target>\r
+       \r
+  <target name="downloadgz" unless="exist" depends="setproxy,testexist">\r
+    <!-- Download and extract the package -->\r
+    <get src="${sourcefile}" dest="${base.path}/file.tar.gz" />\r
+    <gunzip src="${base.path}/file.tar.gz" dest="${base.path}/file.tar"/>\r
+    <untar src="${base.path}/file.tar" dest="${base.path}"/>\r
+    <delete file="${base.path}/file.tar"/>\r
+    <delete file="${base.path}/file.tar.gz"/>\r
+  </target>\r
+\r
+</project>\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
new file mode 100644 (file)
index 0000000..1b594f3
--- /dev/null
@@ -0,0 +1,715 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+import java.lang.management.ManagementFactory;\r
+import java.lang.reflect.Constructor;\r
+import java.lang.reflect.InvocationHandler;\r
+import java.lang.reflect.Proxy;\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.util.ConcurrentModificationException;\r
+import java.util.Iterator;\r
+import java.util.Queue;\r
+import java.util.concurrent.ArrayBlockingQueue;\r
+import java.util.concurrent.BlockingQueue;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.apache.juli.logging.Log;\r
+import org.apache.juli.logging.LogFactory;\r
+\r
+import org.apache.tomcat.jdbc.pool.jmx.ConnectionPoolMBean;\r
+\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import javax.management.InstanceAlreadyExistsException;\r
+import javax.management.MBeanRegistrationException;\r
+import javax.management.MBeanServer;\r
+import javax.management.MalformedObjectNameException;\r
+import javax.management.NotCompliantMBeanException;\r
+import javax.management.ObjectName;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+\r
+public class ConnectionPool {\r
+\r
+    //logger\r
+    protected static Log log = LogFactory.getLog(ConnectionPool.class);\r
+\r
+    //===============================================================================\r
+    //         INSTANCE/QUICK ACCESS VARIABLE\r
+    //===============================================================================\r
+\r
+    /**\r
+     * All the information about the connection pool\r
+     */\r
+    protected PoolProperties poolProperties;\r
+\r
+    /**\r
+     * Contains all the connections that are in use\r
+     */\r
+    protected BlockingQueue<PooledConnection> busy;\r
+\r
+    /**\r
+     * Contains all the idle connections\r
+     */\r
+    protected BlockingQueue<PooledConnection> idle;\r
+\r
+    /**\r
+     * The thread that is responsible for checking abandoned and idle threads\r
+     */\r
+    protected PoolCleaner poolCleaner;\r
+\r
+    /**\r
+     * Pool closed flag\r
+     */\r
+    protected boolean closed = false;\r
+\r
+    /**\r
+     * Size of the pool\r
+     */\r
+    protected AtomicInteger size = new AtomicInteger(0);\r
+\r
+    /**\r
+     * Since newProxyInstance performs the same operation, over and over\r
+     * again, it is much more optimized if we simply store the constructor ourselves.\r
+     */\r
+    protected Constructor proxyClassConstructor;\r
+\r
+\r
+    //===============================================================================\r
+    //         PUBLIC METHODS\r
+    //===============================================================================\r
+\r
+    /**\r
+     * Instantiate a connection pool. This will create connections if initialSize is larger than 0\r
+     * @param prop PoolProperties - all the properties for this connection pool\r
+     * @throws SQLException\r
+     */\r
+    public ConnectionPool(PoolProperties prop) throws SQLException {\r
+        //setup quick access variables and pools\r
+        init(prop);\r
+    }\r
+\r
+    /**\r
+     * Borrows a connection from the pool\r
+     * @return Connection - a java.sql.Connection reflection proxy, wrapping the underlying object.\r
+     * @throws SQLException\r
+     */\r
+    public Connection getConnection() throws SQLException {\r
+        //check out a connection\r
+        PooledConnection con = (PooledConnection)borrowConnection();\r
+        JdbcInterceptor handler = con.getHandler();\r
+        if (handler==null) {\r
+            //build the proxy handler\r
+            handler = new ProxyConnection(this,con);\r
+            //set up the interceptor chain\r
+            String[] proxies = getPoolProperties().getJdbcInterceptorsAsArray();\r
+            for (int i=proxies.length-1; i>=0; i--) {\r
+                try {\r
+                    JdbcInterceptor interceptor =\r
+                        (JdbcInterceptor) Class.forName(proxies[i], true,\r
+                                Thread.currentThread().getContextClassLoader()).newInstance();\r
+                    interceptor.setNext(handler);\r
+                    handler = interceptor;\r
+                }catch(Exception x) {\r
+                    SQLException sx = new SQLException("Unable to instantiate interceptor chain.");\r
+                    sx.initCause(x);\r
+                    throw sx;\r
+                }\r
+            }\r
+            //cache handler for the next iteration\r
+            con.setHandler(handler);\r
+        } else {\r
+            JdbcInterceptor next = handler;\r
+            //we have a cached handler, reset it\r
+            while (next!=null) {\r
+                next.reset(this, con);\r
+                next = next.getNext();\r
+            }\r
+        }\r
+\r
+        try {\r
+            //cache the constructor\r
+            if (proxyClassConstructor == null ) {\r
+                Class proxyClass = Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class});\r
+                proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });\r
+            }\r
+            //create the proxy\r
+            //TODO possible optimization, keep track if this connection was returned properly, and don't generate a new facade\r
+            Connection connection = (Connection)proxyClassConstructor.newInstance(new Object[] { handler });\r
+            //return the connection\r
+            return connection;\r
+        }catch (Exception x) {\r
+            throw new SQLException();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns the name of this pool\r
+     * @return String\r
+     */\r
+    public String getName() {\r
+        return getPoolProperties().getPoolName();\r
+    }\r
+\r
+    /**\r
+     * Returns the pool properties associated with this connection pool\r
+     * @return PoolProperties\r
+     */\r
+    public PoolProperties getPoolProperties() {\r
+        return this.poolProperties;\r
+    }\r
+\r
+    /**\r
+     * Returns the total size of this pool, this includes both busy and idle connections\r
+     * @return int\r
+     */\r
+    public int getSize() {\r
+        return idle.size()+busy.size();\r
+    }\r
+\r
+    /**\r
+     * Returns the number of connections that are in use\r
+     * @return int\r
+     */\r
+    public int getActive() {\r
+        return busy.size();\r
+    }\r
+\r
+    public int getIdle() {\r
+        return idle.size();\r
+    }\r
+\r
+    /**\r
+     * Returns true if {@link #close close} has been called, and the connection pool is unusable\r
+     * @return boolean\r
+     */\r
+    public  boolean isClosed() {\r
+        return this.closed;\r
+    }\r
+\r
+    @Override\r
+    protected void finalize() throws Throwable {\r
+        close(true);\r
+    }\r
+\r
+    /**\r
+     * Closes the pool and all disconnects all idle connections\r
+     * Active connections will be closed upon the {@link java.sql.Connection#close close} method is called\r
+     * on the underlying connection instead of being returned to the pool\r
+     * @param force - true to even close the active connections\r
+     */\r
+    protected void close(boolean force) {\r
+        //are we already closed\r
+        if (this.closed) return;\r
+        //prevent other threads from entering\r
+        this.closed = true;\r
+        //stop background thread\r
+        if (poolCleaner!=null) {\r
+            poolCleaner.stopRunning();\r
+        }\r
+\r
+        /* release all idle connections */\r
+        BlockingQueue<PooledConnection> pool = (idle.size()>0)?idle:(force?busy:idle);\r
+        while (pool.size()>0) {\r
+            try {\r
+                //retrieve the next connection\r
+                PooledConnection con = pool.poll(1000, TimeUnit.MILLISECONDS);\r
+                //close it and retrieve the next one, if one is available\r
+                while (con != null) {\r
+                    //close the connection\r
+                    if (pool==idle)\r
+                        release(con);\r
+                    else\r
+                        abandon(con);\r
+                    con = pool.poll(1000, TimeUnit.MILLISECONDS);\r
+                } //while\r
+            } catch (InterruptedException ex) {\r
+                Thread.currentThread().interrupted();\r
+            }\r
+            if (pool.size()==0 && force && pool!=busy) pool = busy;\r
+        }\r
+        size.set(0);\r
+        if (this.getPoolProperties().isJmxEnabled()) stopJmx();\r
+    } //closePool\r
+\r
+\r
+    //===============================================================================\r
+    //         PROTECTED METHODS\r
+    //===============================================================================\r
+    /**\r
+     * Initialize the connection pool - called from the constructor\r
+     * @param properties PoolProperties - properties used to initialize the pool with\r
+     * @throws SQLException\r
+     */\r
+    protected void init (PoolProperties properties) throws SQLException {\r
+        poolProperties = properties;\r
+        //make space for 10 extra in case we flow over a bit\r
+        busy = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);\r
+        //make space for 10 extra in case we flow over a bit\r
+        idle = new ArrayBlockingQueue<PooledConnection>(properties.getMaxActive(),false);\r
+\r
+        //if the evictor thread is supposed to run, start it now\r
+        if (properties.isPoolSweeperEnabled()) {\r
+            poolCleaner = new PoolCleaner("[Pool-Cleaner]:" + properties.getName(), this, properties.getTimeBetweenEvictionRunsMillis());\r
+            poolCleaner.start();\r
+        } //end if\r
+\r
+        if (properties.getMaxActive()<properties.getInitialSize()) {\r
+            log.warn("initialSize is larger than maxActive, setting initialSize to: "+properties.getMaxActive());\r
+            properties.setInitialSize(properties.getMaxActive());\r
+        }\r
+        if (properties.getMinIdle()>properties.getMaxActive()) {\r
+            log.warn("minIdle is larger than maxActive, setting minIdle to: "+properties.getMaxActive());\r
+            properties.setMinIdle(properties.getMaxActive());\r
+        }\r
+        if (properties.getMaxIdle()>properties.getMaxActive()) {\r
+            log.warn("maxIdle is larger than maxActive, setting maxIdle to: "+properties.getMaxActive());\r
+            properties.setMaxIdle(properties.getMaxActive());\r
+        }\r
+        if (properties.getMaxIdle()<properties.getMinIdle()) {\r
+            log.warn("maxIdle is smaller than minIdle, setting maxIdle to: "+properties.getMinIdle());\r
+            properties.setMaxIdle(properties.getMinIdle());\r
+        }\r
+\r
+\r
+        //initialize the pool with its initial set of members\r
+        PooledConnection[] initialPool = new PooledConnection[poolProperties.getInitialSize()];\r
+        try {\r
+            for (int i = 0; i < initialPool.length; i++) {\r
+                initialPool[i] = this.borrowConnection();\r
+            } //for\r
+\r
+        } catch (SQLException x) {\r
+            close(true);\r
+            throw x;\r
+        } finally {\r
+            //return the members as idle to the pool\r
+            for (int i = 0; i < initialPool.length; i++) {\r
+                if (initialPool[i] != null) {\r
+                    try {this.returnConnection(initialPool[i]);}catch(Exception x){}\r
+                } //end if\r
+            } //for\r
+        } //catch\r
+        if (this.getPoolProperties().isJmxEnabled()) startJmx();\r
+        closed = false;\r
+    }\r
+\r
+\r
+//===============================================================================\r
+//         CONNECTION POOLING IMPL\r
+//===============================================================================\r
+\r
+    /**\r
+     * thread safe way to abandon a connection\r
+     * signals a connection to be abandoned.\r
+     * this will disconnect the connection, and log the stack trace if logAbanded=true\r
+     * @param con PooledConnection\r
+     */\r
+    protected void abandon(PooledConnection con) {\r
+        if (con == null)\r
+            return;\r
+        try {\r
+            con.lock();\r
+            if (getPoolProperties().isLogAbandoned()) {\r
+                log.warn("Connection has been abandoned" + con + ":" +con.getStackTrace());\r
+            }\r
+            con.abandon();\r
+        } finally {\r
+            con.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * thread safe way to release a connection\r
+     * @param con PooledConnection\r
+     */\r
+    protected void release(PooledConnection con) {\r
+        if (con == null)\r
+            return;\r
+        try {\r
+            con.lock();\r
+            con.release();\r
+        } finally {\r
+            con.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Thread safe way to retrieve a connection from the pool\r
+     * @return PooledConnection\r
+     * @throws SQLException\r
+     */\r
+    protected PooledConnection borrowConnection() throws SQLException {\r
+\r
+        if (isClosed()) {\r
+            throw new SQLException("Connection pool closed.");\r
+        } //end if\r
+\r
+        //get the current time stamp\r
+        long now = System.currentTimeMillis();\r
+        //see if there is one available immediately\r
+        PooledConnection con = idle.poll();\r
+\r
+        while (true) {\r
+            if (con!=null) {\r
+                PooledConnection result = borrowConnection(now, con);\r
+                //validation might have failed, in which case null is returned\r
+                if (result!=null) return result;\r
+            }\r
+            if (size.get() < getPoolProperties().getMaxActive()) {\r
+                if (size.addAndGet(1) <= getPoolProperties().getMaxActive()) {\r
+                    return createConnection(now, con);\r
+                } else {\r
+                    size.addAndGet(-1); //restore the value, we didn't create a connection\r
+                }\r
+            } //end if\r
+\r
+            //calculate wait time for this iteration\r
+            long maxWait = (getPoolProperties().getMaxWait()<=0)?Long.MAX_VALUE:getPoolProperties().getMaxWait();\r
+            long timetowait = Math.max(1, maxWait - (System.currentTimeMillis() - now));\r
+            try {\r
+                //retrieve an existing connection\r
+                con = idle.poll(timetowait, TimeUnit.MILLISECONDS);\r
+            } catch (InterruptedException ex) {\r
+                Thread.currentThread().interrupted();\r
+            }\r
+            //we didn't get a connection, lets see if we timed out\r
+            if (con == null) {\r
+                if ((System.currentTimeMillis() - now) >= maxWait) {\r
+                    throw new SQLException(\r
+                        "Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +\r
+                        " seconds, none available["+busy.size()+" in use].");\r
+                } else {\r
+                    //no timeout, lets try again\r
+                    continue;\r
+                }\r
+            }\r
+        } //while\r
+    }\r
+\r
+    protected PooledConnection createConnection(long now, PooledConnection con) {\r
+        //no connections where available we'll create one\r
+        boolean error = false;\r
+        try {\r
+            //connect and validate the connection\r
+            con = create();\r
+            con.lock();\r
+            if (!busy.offer(con)) {\r
+                log.debug("Connection doesn't fit into busy array, connection will not be traceable.");\r
+            }\r
+            con.connect();\r
+            if (con.validate(PooledConnection.VALIDATE_INIT)) {\r
+                //no need to lock a new one, its not contented\r
+                con.setTimestamp(now);\r
+                if (getPoolProperties().isLogAbandoned()) {\r
+                    con.setStackTrace(getThreadDump());\r
+                }\r
+                return con;\r
+            } //end if\r
+        } catch (Exception e) {\r
+            error = true;\r
+            log.error("Unable to create a new JDBC connection.", e);\r
+        } finally {\r
+            if (error ) {\r
+                release(con);\r
+                busy.remove(con);\r
+            }\r
+            con.unlock();\r
+        }//catch\r
+        return null;\r
+    }\r
+\r
+    protected PooledConnection borrowConnection(long now, PooledConnection con) {\r
+        //we have a connection, lets set it up\r
+        boolean setToNull = false;\r
+        try {\r
+            con.lock();\r
+            if (con.isDiscarded()) {\r
+                //connection has already been disconnected\r
+                setToNull = true;\r
+            } else if (con.validate(PooledConnection.VALIDATE_BORROW)) {\r
+                //set the timestamp\r
+                con.setTimestamp(now);\r
+                if (getPoolProperties().isLogAbandoned()) {\r
+                    //set the stack trace for this pool\r
+                    con.setStackTrace(getThreadDump());\r
+                }\r
+                if (!busy.offer(con)) {\r
+                    log.debug("Connection doesn't fit into busy array, connection will not be traceable.");\r
+                }\r
+                return con;\r
+            } else {\r
+                /*if the object wasn't validated, we may as well remove it*/\r
+                release(con);\r
+                setToNull = true;\r
+            } //end if\r
+        } finally {\r
+            con.unlock();\r
+            if (setToNull) {\r
+                con = null;\r
+            }\r
+        }\r
+        return con;\r
+    }\r
+\r
+    /**\r
+     * Returns a connection to the pool\r
+     * @param con PooledConnection\r
+     */\r
+    protected void returnConnection(PooledConnection con) {\r
+        if (isClosed()) {\r
+            //if the connection pool is closed\r
+            //close the connection instead of returning it\r
+            release(con);\r
+            return;\r
+        } //end if\r
+\r
+        if (con != null) {\r
+            try {\r
+                con.lock();\r
+\r
+                if (busy.remove(con)) {\r
+                    if ((!con.isDiscarded()) && (!isClosed()) &&\r
+                            con.validate(PooledConnection.VALIDATE_RETURN)) {\r
+                        con.setStackTrace(null);\r
+                        con.setTimestamp(System.currentTimeMillis());\r
+                        if (!idle.offer(con)) {\r
+                            if (log.isDebugEnabled()) {\r
+                                log.debug("Connection ["+con+"] will be closed and not returned to the pool, idle.offer failed.");\r
+                            }\r
+                            release(con);\r
+                        }\r
+                    } else {\r
+                        if (log.isDebugEnabled()) {\r
+                            log.debug("Connection ["+con+"] will be closed and not returned to the pool.");\r
+                        }\r
+                        release(con);\r
+                    } //end if\r
+                } else {\r
+                    if (log.isDebugEnabled()) {\r
+                        log.debug("Connection ["+con+"] will be closed and not returned to the pool, busy.remove failed.");\r
+                    }\r
+                    release(con);\r
+                }\r
+            } finally {\r
+                con.unlock();\r
+            }\r
+        } //end if\r
+    } //checkIn\r
+\r
+    public void checkAbandoned() {\r
+        try {\r
+            long now = System.currentTimeMillis();\r
+            Iterator<PooledConnection> locked = busy.iterator();\r
+            while (locked.hasNext()) {\r
+                PooledConnection con = locked.next();\r
+                boolean setToNull = false;\r
+                try {\r
+                    con.lock();\r
+                    //the con has been returned to the pool\r
+                    //ignore it\r
+                    if (idle.contains(con))\r
+                        continue;\r
+                    long time = con.getTimestamp();\r
+                    if ((now - time) > con.getAbandonTimeout()) {\r
+                        busy.remove(con);\r
+                        abandon(con);\r
+                        release(con);\r
+                        setToNull = true;\r
+                    } else {\r
+                        //do nothing\r
+                    } //end if\r
+                } finally {\r
+                    con.unlock();\r
+                    if (setToNull)\r
+                        con = null;\r
+                }\r
+            } //while\r
+        } catch (ConcurrentModificationException e) {\r
+            log.debug("checkAbandoned failed." ,e);\r
+        } catch (Exception e) {\r
+            log.warn("checkAbandoned failed, it will be retried.",e);\r
+        }\r
+    }\r
+\r
+    public void checkIdle() {\r
+        try {\r
+            long now = System.currentTimeMillis();\r
+            Iterator<PooledConnection> unlocked = idle.iterator();\r
+            while ( (idle.size()>=getPoolProperties().getMinIdle()) && unlocked.hasNext()) {\r
+                PooledConnection con = unlocked.next();\r
+                boolean setToNull = false;\r
+                try {\r
+                    con.lock();\r
+                    //the con been taken out, we can't clean it up\r
+                    if (busy.contains(con))\r
+                        continue;\r
+                    long time = con.getTimestamp();\r
+                    if (((now - time) > con.getReleaseTime()) && (getSize()>getPoolProperties().getMinIdle())) {\r
+                        release(con);\r
+                        idle.remove(con);\r
+                        setToNull = true;\r
+                    } else {\r
+                        //do nothing\r
+                    } //end if\r
+                } finally {\r
+                    con.unlock();\r
+                    if (setToNull)\r
+                        con = null;\r
+                }\r
+            } //while\r
+        } catch (ConcurrentModificationException e) {\r
+            log.debug("checkIdle failed." ,e);\r
+        } catch (Exception e) {\r
+            log.warn("checkIdle failed, it will be retried.",e);\r
+        }\r
+\r
+    }\r
+\r
+    public void testAllIdle() {\r
+        try {\r
+            Iterator<PooledConnection> unlocked = idle.iterator();\r
+            while (unlocked.hasNext()) {\r
+                PooledConnection con = unlocked.next();\r
+                try {\r
+                    con.lock();\r
+                    //the con been taken out, we can't clean it up\r
+                    if (busy.contains(con))\r
+                        continue;\r
+                    if (!con.validate(PooledConnection.VALIDATE_IDLE)) {\r
+                        idle.remove(con);\r
+                        con.release();\r
+                    }\r
+                } finally {\r
+                    con.unlock();\r
+                }\r
+            } //while\r
+        } catch (ConcurrentModificationException e) {\r
+            log.debug("testAllIdle failed." ,e);\r
+        } catch (Exception e) {\r
+            log.warn("testAllIdle failed, it will be retried.",e);\r
+        }\r
+\r
+    }\r
+\r
+\r
+    protected static String getThreadDump() {\r
+        Exception x = new Exception();\r
+        x.fillInStackTrace();\r
+        return getStackTrace(x);\r
+    }\r
+\r
+    protected static String getStackTrace(Exception x) {\r
+        if (x == null) {\r
+            return null;\r
+        } else {\r
+            java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();\r
+            java.io.PrintStream writer = new java.io.PrintStream(bout);\r
+            x.printStackTrace(writer);\r
+            String result = bout.toString();\r
+            return result;\r
+        } //end if\r
+    }\r
+\r
+\r
+    protected PooledConnection create() throws java.lang.Exception {\r
+        PooledConnection con = new PooledConnection(getPoolProperties(), this);\r
+        return con;\r
+    }\r
+\r
+    protected void finalize(PooledConnection con) {\r
+        size.addAndGet(-1);\r
+    }\r
+\r
+    public void startJmx() {\r
+        try {\r
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();\r
+            ObjectName name = new ObjectName("org.apache.tomcat.jdbc.pool.jmx:type=ConnectionPool,name="+getName());\r
+            mbs.registerMBean(new org.apache.tomcat.jdbc.pool.jmx.ConnectionPool(this), name);\r
+        } catch (Exception x) {\r
+            log.warn("Unable to start JMX integration for connection pool. Instance["+getName()+"] can't be monitored.",x);\r
+        }\r
+    }\r
+\r
+    public void stopJmx() {\r
+        try {\r
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();\r
+            ObjectName name = new ObjectName("org.apache.tomcat.jdbc.pool.jmx:type=ConnectionPool,name="+getName());\r
+            mbs.unregisterMBean(name);\r
+        }catch (Exception x) {\r
+            log.warn("Unable to stop JMX integration for connection pool. Instance["+getName()+"].",x);\r
+        }\r
+    }\r
+\r
+\r
+    protected class PoolCleaner extends Thread {\r
+        protected ConnectionPool pool;\r
+        protected long sleepTime;\r
+        protected boolean run = true;\r
+        PoolCleaner(String name, ConnectionPool pool, long sleepTime) {\r
+            super(name);\r
+            this.setDaemon(true);\r
+            this.pool = pool;\r
+            this.sleepTime = sleepTime;\r
+            if (sleepTime <= 0) {\r
+                pool.log.warn("Database connection pool evicter thread interval is set to 0, defaulting to 30 seconds");\r
+                this.sleepTime = 1000 * 30;\r
+            } else if (sleepTime < 1000) {\r
+                pool.log.warn("Database connection pool evicter thread interval is set to lower than 1 second.");\r
+            }\r
+        }\r
+\r
+        public void run() {\r
+            while (run) {\r
+                try {\r
+                    sleep(sleepTime);\r
+                } catch (InterruptedException e) {\r
+                    // ignore it\r
+                    Thread.currentThread().interrupted();\r
+                    continue;\r
+                } //catch\r
+\r
+                if (pool.isClosed()) {\r
+                    if (pool.getSize() <= 0) {\r
+                        run = false;\r
+                    }\r
+                } else {\r
+                    try {\r
+                        if (pool.getPoolProperties().isRemoveAbandoned())\r
+                            pool.checkAbandoned();\r
+                        if (pool.getPoolProperties().getMaxIdle()<pool.idle.size())\r
+                            pool.checkIdle();\r
+                        if (pool.getPoolProperties().isTestWhileIdle())\r
+                            pool.testAllIdle();\r
+                    } catch (Exception x) {\r
+                        pool.log.error("", x);\r
+                    } //catch\r
+                } //end if\r
+            } //while\r
+        } //run\r
+\r
+        public void stopRunning() {\r
+            run = false;\r
+            interrupt();\r
+        }\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSource.java
new file mode 100644 (file)
index 0000000..7241117
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+\r
+/**\r
+ * A DataSource that can be instantiated through IoC and implements the DataSource interface\r
+ * since the DataSourceProxy is used as a generic proxy\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class DataSource extends DataSourceProxy implements javax.sql.DataSource {\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java
new file mode 100644 (file)
index 0000000..58265bf
--- /dev/null
@@ -0,0 +1,427 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.lang.reflect.InvocationHandler;\r
+import java.lang.reflect.Method;\r
+import java.lang.reflect.Proxy;\r
+import java.sql.Connection;\r
+import java.util.HashMap;\r
+import java.util.Hashtable;\r
+import java.util.Properties;\r
+\r
+import javax.naming.Context;\r
+import javax.naming.Name;\r
+import javax.naming.RefAddr;\r
+import javax.naming.Reference;\r
+import javax.naming.spi.ObjectFactory;\r
+import javax.sql.DataSource;\r
+\r
+import org.apache.juli.logging.Log;\r
+import org.apache.juli.logging.LogFactory;\r
+\r
+/**\r
+ * <p>JNDI object factory that creates an instance of\r
+ * <code>BasicDataSource</code> that has been configured based on the\r
+ * <code>RefAddr</code> values of the specified <code>Reference</code>,\r
+ * which must match the names and data types of the\r
+ * <code>BasicDataSource</code> bean properties.</p>\r
+ * <br/>\r
+ * Properties available for configuration:<br/>\r
+ * <a href="http://commons.apache.org/dbcp/configuration.html">Commons DBCP properties</a><br/>\r
+ *<ol>\r
+ *  <li>initSQL - A query that gets executed once, right after the connection is established.</li>\r
+ *  <li>testOnConnect - run validationQuery after connection has been established.</li>\r
+ *  <li>validationInterval - avoid excess validation, only run validation at most at this frequency - time in milliseconds.</li>\r
+ *  <li>jdbcInterceptors - a semicolon separated list of classnames extending {@link JdbcInterceptor} class.</li>\r
+ *  <li>jmxEnabled - true of false, whether to register the pool with JMX.</li>\r
+ *</ol>\r
+ * @author Craig R. McClanahan\r
+ * @author Dirk Verbeeck\r
+ * @author Filip Hanik\r
+ */\r
+public class DataSourceFactory implements ObjectFactory {\r
+    protected static Log log = LogFactory.getLog(DataSourceFactory.class);\r
+\r
+    protected final static String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";\r
+    protected final static String PROP_DEFAULTREADONLY = "defaultReadOnly";\r
+    protected final static String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";\r
+    protected final static String PROP_DEFAULTCATALOG = "defaultCatalog";\r
+    \r
+    protected final static String PROP_DRIVERCLASSNAME = "driverClassName";\r
+    protected final static String PROP_PASSWORD = "password";\r
+    protected final static String PROP_URL = "url";\r
+    protected final static String PROP_USERNAME = "username";\r
+\r
+    protected final static String PROP_MAXACTIVE = "maxActive";\r
+    protected final static String PROP_MAXIDLE = "maxIdle";\r
+    protected final static String PROP_MINIDLE = "minIdle";\r
+    protected final static String PROP_INITIALSIZE = "initialSize";\r
+    protected final static String PROP_MAXWAIT = "maxWait";\r
+    \r
+    protected final static String PROP_TESTONBORROW = "testOnBorrow";\r
+    protected final static String PROP_TESTONRETURN = "testOnReturn";\r
+    protected final static String PROP_TESTWHILEIDLE = "testWhileIdle";\r
+    protected final static String PROP_TESTONCONNECT = "testOnConnect";\r
+    protected final static String PROP_VALIDATIONQUERY = "validationQuery";\r
+    \r
+    protected final static String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";\r
+    protected final static String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";\r
+    protected final static String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";\r
+    \r
+    protected final static String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";\r
+    \r
+    protected final static String PROP_REMOVEABANDONED = "removeAbandoned";\r
+    protected final static String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";\r
+    protected final static String PROP_LOGABANDONED = "logAbandoned";\r
+    \r
+    protected final static String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";\r
+    protected final static String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";\r
+    protected final static String PROP_CONNECTIONPROPERTIES = "connectionProperties";\r
+    \r
+    protected final static String PROP_INITSQL = "initSQL";\r
+    protected final static String PROP_INTERCEPTORS = "jdbcInterceptors";\r
+    protected final static String PROP_VALIDATIONINTERVAL = "validationInterval";\r
+    protected final static String PROP_JMX_ENABLED = "jmxEnabled";\r
+    \r
+    public static final int UNKNOWN_TRANSACTIONISOLATION = -1;\r
+\r
+\r
+    protected final static String[] ALL_PROPERTIES = {\r
+        PROP_DEFAULTAUTOCOMMIT,\r
+        PROP_DEFAULTREADONLY,\r
+        PROP_DEFAULTTRANSACTIONISOLATION,\r
+        PROP_DEFAULTCATALOG,\r
+        PROP_DRIVERCLASSNAME,\r
+        PROP_MAXACTIVE,\r
+        PROP_MAXIDLE,\r
+        PROP_MINIDLE,\r
+        PROP_INITIALSIZE,\r
+        PROP_MAXWAIT,\r
+        PROP_TESTONBORROW,\r
+        PROP_TESTONRETURN,\r
+        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,\r
+        PROP_NUMTESTSPEREVICTIONRUN,\r
+        PROP_MINEVICTABLEIDLETIMEMILLIS,\r
+        PROP_TESTWHILEIDLE,\r
+        PROP_TESTONCONNECT,\r
+        PROP_PASSWORD,\r
+        PROP_URL,\r
+        PROP_USERNAME,\r
+        PROP_VALIDATIONQUERY,\r
+        PROP_VALIDATIONINTERVAL,\r
+        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,\r
+        PROP_REMOVEABANDONED,\r
+        PROP_REMOVEABANDONEDTIMEOUT,\r
+        PROP_LOGABANDONED,\r
+        PROP_POOLPREPAREDSTATEMENTS,\r
+        PROP_MAXOPENPREPAREDSTATEMENTS,\r
+        PROP_CONNECTIONPROPERTIES,\r
+        PROP_INITSQL,\r
+        PROP_INTERCEPTORS,\r
+        PROP_JMX_ENABLED\r
+    };\r
+\r
+    // -------------------------------------------------- ObjectFactory Methods\r
+\r
+    /**\r
+     * <p>Create and return a new <code>BasicDataSource</code> instance.  If no\r
+     * instance can be created, return <code>null</code> instead.</p>\r
+     *\r
+     * @param obj The possibly null object containing location or\r
+     *  reference information that can be used in creating an object\r
+     * @param name The name of this object relative to <code>nameCtx</code>\r
+     * @param nameCtx The context relative to which the <code>name</code>\r
+     *  parameter is specified, or <code>null</code> if <code>name</code>\r
+     *  is relative to the default initial context\r
+     * @param environment The possibly null environment that is used in\r
+     *  creating this object\r
+     *\r
+     * @exception Exception if an exception occurs creating the instance\r
+     */\r
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,\r
+                                    Hashtable environment) throws Exception {\r
+\r
+        // We only know how to deal with <code>javax.naming.Reference</code>s\r
+        // that specify a class name of "javax.sql.DataSource"\r
+        if ((obj == null) || !(obj instanceof Reference)) {\r
+            return null;\r
+        }\r
+        Reference ref = (Reference) obj;\r
+        if (!"javax.sql.DataSource".equals(ref.getClassName())) {\r
+            return null;\r
+        }\r
+\r
+        Properties properties = new Properties();\r
+        for (int i = 0; i < ALL_PROPERTIES.length; i++) {\r
+            String propertyName = ALL_PROPERTIES[i];\r
+            RefAddr ra = ref.get(propertyName);\r
+            if (ra != null) {\r
+                String propertyValue = ra.getContent().toString();\r
+                properties.setProperty(propertyName, propertyValue);\r
+            }\r
+        }\r
+\r
+        return createDataSource(properties);\r
+    }\r
+\r
+    /**\r
+     * Creates and configures a {@link BasicDataSource} instance based on the\r
+     * given properties.\r
+     *\r
+     * @param properties the datasource configuration properties\r
+     * @throws Exception if an error occurs creating the data source\r
+     */\r
+    public static DataSource createDataSource(Properties properties) throws Exception {\r
+        org.apache.tomcat.jdbc.pool.DataSourceProxy dataSource = new org.apache.tomcat.jdbc.pool.DataSourceProxy();\r
+\r
+        String value = null;\r
+\r
+        value = properties.getProperty(PROP_DEFAULTAUTOCOMMIT);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setDefaultAutoCommit(Boolean.valueOf(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_DEFAULTREADONLY);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setDefaultReadOnly(Boolean.valueOf(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_DEFAULTTRANSACTIONISOLATION);\r
+        if (value != null) {\r
+            int level = UNKNOWN_TRANSACTIONISOLATION;\r
+            if ("NONE".equalsIgnoreCase(value)) {\r
+                level = Connection.TRANSACTION_NONE;\r
+            } else if ("READ_COMMITTED".equalsIgnoreCase(value)) {\r
+                level = Connection.TRANSACTION_READ_COMMITTED;\r
+            } else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {\r
+                level = Connection.TRANSACTION_READ_UNCOMMITTED;\r
+            } else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {\r
+                level = Connection.TRANSACTION_REPEATABLE_READ;\r
+            } else if ("SERIALIZABLE".equalsIgnoreCase(value)) {\r
+                level = Connection.TRANSACTION_SERIALIZABLE;\r
+            } else {\r
+                try {\r
+                    level = Integer.parseInt(value);\r
+                } catch (NumberFormatException e) {\r
+                    System.err.println("Could not parse defaultTransactionIsolation: " + value);\r
+                    System.err.println("WARNING: defaultTransactionIsolation not set");\r
+                    System.err.println("using default value of database driver");\r
+                    level = UNKNOWN_TRANSACTIONISOLATION;\r
+                }\r
+            }\r
+            dataSource.getPoolProperties().setDefaultTransactionIsolation(level);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_DEFAULTCATALOG);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setDefaultCatalog(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_DRIVERCLASSNAME);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setDriverClassName(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MAXACTIVE);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setMaxActive(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MAXIDLE);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setMaxIdle(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MINIDLE);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setMinIdle(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_INITIALSIZE);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setInitialSize(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MAXWAIT);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setMaxWait(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_TESTONBORROW);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setTestOnBorrow(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_TESTONRETURN);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setTestOnReturn(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_TESTONCONNECT);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setTestOnConnect(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_TIMEBETWEENEVICTIONRUNSMILLIS);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setTimeBetweenEvictionRunsMillis(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_NUMTESTSPEREVICTIONRUN);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setNumTestsPerEvictionRun(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MINEVICTABLEIDLETIMEMILLIS);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setMinEvictableIdleTimeMillis(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_TESTWHILEIDLE);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setTestWhileIdle(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_PASSWORD);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setPassword(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_URL);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setUrl(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_USERNAME);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setUsername(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_VALIDATIONQUERY);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setValidationQuery(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_VALIDATIONINTERVAL);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setValidationInterval(Long.parseLong(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().\r
+                setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_REMOVEABANDONED);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setRemoveAbandoned(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_REMOVEABANDONEDTIMEOUT);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setRemoveAbandonedTimeout(Integer.parseInt(value));\r
+        }\r
+\r
+        value = properties.getProperty(PROP_LOGABANDONED);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setLogAbandoned(Boolean.valueOf(value).booleanValue());\r
+        }\r
+\r
+        value = properties.getProperty(PROP_POOLPREPAREDSTATEMENTS);\r
+        if (value != null) {\r
+            log.warn(PROP_POOLPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");\r
+        }\r
+\r
+        value = properties.getProperty(PROP_MAXOPENPREPAREDSTATEMENTS);\r
+        if (value != null) {\r
+            log.warn(PROP_MAXOPENPREPAREDSTATEMENTS + " is not a valid setting, it will have no effect.");\r
+        }\r
+\r
+        value = properties.getProperty(PROP_CONNECTIONPROPERTIES);\r
+        if (value != null) {\r
+            Properties p = getProperties(value);\r
+            dataSource.getPoolProperties().setDbProperties(p);\r
+        } else {\r
+            dataSource.getPoolProperties().setDbProperties(new Properties());\r
+        }\r
+\r
+        dataSource.getPoolProperties().getDbProperties().setProperty("user",dataSource.getPoolProperties().getUsername());\r
+        dataSource.getPoolProperties().getDbProperties().setProperty("password",dataSource.getPoolProperties().getPassword());\r
+\r
+        value = properties.getProperty(PROP_INITSQL);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setInitSQL(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_INTERCEPTORS);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setJdbcInterceptors(value);\r
+        }\r
+\r
+        value = properties.getProperty(PROP_JMX_ENABLED);\r
+        if (value != null) {\r
+            dataSource.getPoolProperties().setJmxEnabled(Boolean.parseBoolean(value));\r
+        }\r
+\r
+        // Return the configured DataSource instance\r
+        DataSource ds = getDataSource(dataSource);\r
+        return ds;\r
+    }\r
+\r
+    public static DataSource getDataSource(org.apache.tomcat.jdbc.pool.DataSourceProxy dataSource) {\r
+        DataSourceHandler handler = new DataSourceHandler(dataSource);\r
+        DataSource ds = (DataSource)Proxy.newProxyInstance(DataSourceFactory.class.getClassLoader(), new Class[] {javax.sql.DataSource.class}, handler);\r
+        return ds;\r
+    }\r
+\r
+    /**\r
+     * <p>Parse properties from the string. Format of the string must be [propertyName=property;]*<p>\r
+     * @param propText\r
+     * @return Properties\r
+     * @throws Exception\r
+     */\r
+    static protected Properties getProperties(String propText) throws Exception {\r
+        Properties p = new Properties();\r
+        if (propText != null) {\r
+            p.load(new ByteArrayInputStream(propText.replace(';', '\n').\r
+                                            getBytes()));\r
+        }\r
+        return p;\r
+    }\r
+\r
+    protected static class DataSourceHandler implements InvocationHandler {\r
+        protected org.apache.tomcat.jdbc.pool.DataSourceProxy datasource = null;\r
+        protected static HashMap<Method,Method> methods = new HashMap<Method,Method>();\r
+        public DataSourceHandler(org.apache.tomcat.jdbc.pool.DataSourceProxy ds) {\r
+            this.datasource = ds;\r
+        }\r
+\r
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+            Method m = methods.get(method);\r
+            if (m==null) {\r
+                m = datasource.getClass().getMethod(method.getName(), method.getParameterTypes());\r
+                methods.put(method, m);\r
+            }\r
+            return m.invoke(datasource, args);\r
+        }\r
+\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
new file mode 100644 (file)
index 0000000..878585c
--- /dev/null
@@ -0,0 +1,304 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+import java.io.PrintWriter;\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.util.Iterator;\r
+\r
+import org.apache.juli.logging.Log;\r
+import org.apache.juli.logging.LogFactory;\r
+\r
+/**\r
+ *\r
+ * <p>Title: Uber Pool</p>\r
+ *\r
+ * <p>Description: A simple, yet efficient and powerful connection pool</p>\r
+ *\r
+ * <p>Copyright: Copyright (c) 2008 Filip Hanik</p>\r
+ *\r
+ * <p> </p>\r
+ *\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+\r
+public class DataSourceProxy  {\r
+    protected static Log log = LogFactory.getLog(DataSourceProxy.class);\r
+    \r
+    protected Driver driver;\r
+    protected PoolProperties poolProperties = new PoolProperties();\r
+\r
+    public DataSourceProxy() {\r
+    }\r
+\r
+\r
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
+        // we are not a wrapper of anything\r
+        return false;\r
+    }\r
+\r
+\r
+    public <T> T unwrap(Class<T> iface) throws SQLException {\r
+        //we can't unwrap anything\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public Connection getConnection(String username, String password) throws SQLException {\r
+        return getConnection();\r
+    }\r
+\r
+    public PoolProperties getPoolProperties() {\r
+        return poolProperties;\r
+    }\r
+\r
+    /**\r
+     * Sets up the connection pool, by creating a pooling driver.\r
+     * @return Driver\r
+     * @throws SQLException\r
+     */\r
+    public synchronized Driver createDriver() throws SQLException {\r
+        if (driver != null) {\r
+            return driver;\r
+        } else {\r
+            driver = new org.apache.tomcat.jdbc.pool.Driver(getPoolProperties());\r
+            return driver;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+\r
+    public Connection getConnection() throws SQLException {\r
+        if (driver == null)\r
+            driver = createDriver();\r
+        return driver.connect(poolProperties.getPoolName(), null);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public PooledConnection getPooledConnection() throws SQLException {\r
+        return (PooledConnection) getConnection();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public PooledConnection getPooledConnection(String username,\r
+                                                String password) throws SQLException {\r
+        return (PooledConnection) getConnection();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public PrintWriter getLogWriter() throws SQLException {\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public void setLogWriter(PrintWriter out) throws SQLException {\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public int getLoginTimeout() {\r
+        if (poolProperties == null) {\r
+            return 0;\r
+        } else {\r
+            return poolProperties.getMaxWait() / 1000;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public void setLoginTimeout(int i) {\r
+        if (poolProperties == null) {\r
+            return;\r
+        } else {\r
+            poolProperties.setMaxWait(1000 * i);\r
+        }\r
+\r
+    }\r
+\r
+\r
+    public void close() {\r
+        close(false);\r
+    }\r
+    public void close(boolean all) {\r
+        try {\r
+            if (driver != null) {\r
+                Driver d = driver;\r
+                driver = null;\r
+                d.closePool(poolProperties.getPoolName(), all);\r
+            }\r
+        }catch (Exception x) {\r
+            x.printStackTrace();\r
+        }\r
+    }\r
+\r
+    protected void finalize() throws Throwable {\r
+        //terminate the pool?\r
+        close(true);\r
+    }\r
+\r
+    public int getPoolSize() throws SQLException{\r
+        if (driver == null)\r
+            driver = createDriver();\r
+        return driver.getPool(getPoolProperties().getPoolName()).getSize();\r
+    }\r
+\r
+   public String toString() {\r
+        return super.toString()+"{"+getPoolProperties()+"}";\r
+    }\r
+\r
+/*-----------------------------------------------------------------------*/\r
+//      PROPERTIES WHEN NOT USED WITH FACTORY\r
+/*------------------------------------------------------------------------*/\r
+    public void setPoolProperties(PoolProperties poolProperties) {\r
+        this.poolProperties = poolProperties;\r
+    }\r
+\r
+    public void setDriverClassName(String driverClassName) {\r
+        this.poolProperties.setDriverClassName(driverClassName);\r
+    }\r
+\r
+    public void setInitialSize(int initialSize) {\r
+        this.poolProperties.setInitialSize(initialSize);\r
+    }\r
+\r
+    public void setInitSQL(String initSQL) {\r
+        this.poolProperties.setInitSQL(initSQL);\r
+    }\r
+\r
+    public void setLogAbandoned(boolean logAbandoned) {\r
+        this.poolProperties.setLogAbandoned(logAbandoned);\r
+    }\r
+\r
+    public void setMaxActive(int maxActive) {\r
+        this.poolProperties.setMaxIdle(maxActive);\r
+    }\r
+\r
+    public void setMaxIdle(int maxIdle) {\r
+        this.poolProperties.setMaxIdle(maxIdle);\r
+    }\r
+\r
+    public void setMaxWait(int maxWait) {\r
+        this.poolProperties.setMaxWait(maxWait);\r
+    }\r
+\r
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {\r
+        this.poolProperties.setMinEvictableIdleTimeMillis(\r
+            minEvictableIdleTimeMillis);\r
+    }\r
+\r
+    public void setMinIdle(int minIdle) {\r
+        this.setMinIdle(minIdle);\r
+    }\r
+\r
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {\r
+        this.poolProperties.setNumTestsPerEvictionRun(numTestsPerEvictionRun);\r
+    }\r
+\r
+    public void setPassword(String password) {\r
+        this.poolProperties.setPassword(password);\r
+        this.poolProperties.getDbProperties().setProperty("password",this.poolProperties.getPassword());\r
+    }\r
+\r
+    public void setRemoveAbandoned(boolean removeAbandoned) {\r
+        this.poolProperties.setRemoveAbandoned(removeAbandoned);\r
+    }\r
+\r
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {\r
+        this.poolProperties.setRemoveAbandonedTimeout(removeAbandonedTimeout);\r
+    }\r
+\r
+    public void setTestOnBorrow(boolean testOnBorrow) {\r
+        this.poolProperties.setTestOnBorrow(testOnBorrow);\r
+    }\r
+\r
+    public void setTestOnConnect(boolean testOnConnect) {\r
+        this.poolProperties.setTestOnConnect(testOnConnect);\r
+    }\r
+\r
+    public void setTestOnReturn(boolean testOnReturn) {\r
+        this.poolProperties.setTestOnReturn(testOnReturn);\r
+    }\r
+\r
+    public void setTestWhileIdle(boolean testWhileIdle) {\r
+        this.poolProperties.setTestWhileIdle(testWhileIdle);\r
+    }\r
+\r
+    public void setTimeBetweenEvictionRunsMillis(int\r
+                                                 timeBetweenEvictionRunsMillis) {\r
+        this.poolProperties.setTimeBetweenEvictionRunsMillis(\r
+            timeBetweenEvictionRunsMillis);\r
+    }\r
+\r
+    public void setUrl(String url) {\r
+        this.poolProperties.setUrl(url);\r
+    }\r
+\r
+    public void setUsername(String username) {\r
+        this.poolProperties.setUsername(username);\r
+        this.poolProperties.getDbProperties().setProperty("user",getPoolProperties().getUsername());\r
+    }\r
+\r
+    public void setValidationInterval(long validationInterval) {\r
+        this.poolProperties.setValidationInterval(validationInterval);\r
+    }\r
+\r
+    public void setValidationQuery(String validationQuery) {\r
+        this.poolProperties.setValidationQuery(validationQuery);\r
+    }\r
+\r
+    public void setJdbcInterceptors(String interceptors) {\r
+        this.getPoolProperties().setJdbcInterceptors(interceptors);\r
+    }\r
+\r
+    public void setJmxEnabled(boolean enabled) {\r
+        this.getPoolProperties().setJmxEnabled(enabled);\r
+    }\r
+    \r
+    public void setConnectionProperties(String properties) {\r
+        try {\r
+            java.util.Properties prop = DataSourceFactory.getProperties(properties);\r
+            Iterator i = prop.keySet().iterator();\r
+            while (i.hasNext()) {\r
+                String key = (String)i.next();\r
+                String value = prop.getProperty(key);\r
+                getPoolProperties().getDbProperties().setProperty(key, value);\r
+            }\r
+            \r
+        }catch (Exception x) {\r
+            log.error("Unable to parse connection properties.", x);\r
+            throw new RuntimeException(x);\r
+        }\r
+    }\r
+\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/Driver.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/Driver.java
new file mode 100644 (file)
index 0000000..9e03825
--- /dev/null
@@ -0,0 +1,121 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+\r
+import java.sql.Connection;\r
+import java.sql.DriverPropertyInfo;\r
+import java.sql.SQLException;\r
+import java.util.HashMap;\r
+import java.util.Properties;\r
+\r
+import org.apache.juli.logging.Log;\r
+import org.apache.juli.logging.LogFactory;\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class Driver implements java.sql.Driver {\r
+\r
+    protected static Log log = LogFactory.getLog(Driver.class);\r
+\r
+    protected static HashMap pooltable = new HashMap(11);\r
+\r
+    public Driver() throws SQLException {\r
+    }\r
+\r
+    public Driver(PoolProperties properties) throws SQLException {\r
+        init(properties);\r
+    } //Driver\r
+\r
+    public void init(PoolProperties properties) throws SQLException {\r
+        if (pooltable.get(properties.getPoolName()) != null)\r
+            throw new SQLException("Pool identified by:" + properties.getPoolName() + " already exists.");\r
+        ConnectionPool pool = new ConnectionPool(properties);\r
+        pooltable.put(properties.getPoolName(), pool);\r
+    }\r
+\r
+    public void closePool(String url, boolean all) throws SQLException {\r
+        ConnectionPool pool = (ConnectionPool) pooltable.get(url);\r
+        if (pool == null) {\r
+            throw new SQLException("No connection pool established for URL:" + url);\r
+        } else {\r
+            pool.close(all);\r
+        }\r
+        pooltable.remove(url);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public Connection connect(String url, Properties info) throws SQLException {\r
+        ConnectionPool pool = (ConnectionPool) pooltable.get(url);\r
+        if (pool == null) {\r
+            throw new SQLException("No connection pool established for URL:" + url);\r
+        } else {\r
+            try {\r
+                return pool.getConnection();\r
+            } catch (SQLException forward) {\r
+                throw forward;\r
+            } catch (Exception e) {\r
+                throw new SQLException("Unknow pool exception:" + ConnectionPool.getStackTrace(e));\r
+            } //catch\r
+        } //end if\r
+    } //connect\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public boolean acceptsURL(String url) throws SQLException {\r
+        /* check if the driver has a connection pool with that name */\r
+        return (pooltable.get(url) != null ? true : false);\r
+    } //acceptsUrl\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws\r
+        SQLException {\r
+        return new DriverPropertyInfo[0];\r
+    } //getPropertyInfo\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public int getMajorVersion() {\r
+        return 1;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public int getMinorVersion() {\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public boolean jdbcCompliant() {\r
+        return true;\r
+    }\r
+\r
+    public ConnectionPool getPool(String url) throws SQLException {\r
+        return (ConnectionPool) pooltable.get(url);\r
+    }\r
+\r
+} //class\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
new file mode 100644 (file)
index 0000000..67d1086
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+import java.lang.reflect.InvocationHandler;\r
+import java.lang.reflect.Method;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public abstract class JdbcInterceptor implements InvocationHandler {\r
+    public  static final String CLOSE_VAL = "close";\r
+\r
+    private JdbcInterceptor next = null;\r
+\r
+    public JdbcInterceptor() {\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+        if (getNext()!=null) return getNext().invoke(this,method,args);\r
+        else throw new NullPointerException();\r
+    }\r
+\r
+    public JdbcInterceptor getNext() {\r
+        return next;\r
+    }\r
+\r
+    public void setNext(JdbcInterceptor next) {\r
+        this.next = next;\r
+    }\r
+\r
+    public abstract void reset(ConnectionPool parent, PooledConnection con);\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
new file mode 100644 (file)
index 0000000..6f94d36
--- /dev/null
@@ -0,0 +1,388 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.Properties;\r
+/**\r
+ * @author Filip Hanik\r
+ *\r
+ */\r
+public class PoolProperties {\r
+    protected static volatile int poolCounter = 1;\r
+    protected Properties dbProperties = new Properties();\r
+    protected String url = null;\r
+    protected String driverClassName = null;\r
+    protected Boolean defaultAutoCommit = null;\r
+    protected Boolean defaultReadOnly = null;\r
+    protected int defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;\r
+    protected String defaultCatalog = null;\r
+    protected String connectionProperties;\r
+    protected int initialSize = 10;\r
+    protected int maxActive = 100;\r
+    protected int maxIdle = maxActive;\r
+    protected int minIdle = initialSize;\r
+    protected int maxWait = 30000;\r
+    protected String validationQuery;\r
+    protected boolean testOnBorrow = false;\r
+    protected boolean testOnReturn = false;\r
+    protected boolean testWhileIdle = false;\r
+    protected int timeBetweenEvictionRunsMillis = 5000;\r
+    protected int numTestsPerEvictionRun;\r
+    protected int minEvictableIdleTimeMillis = 60000;\r
+    protected boolean accessToUnderlyingConnectionAllowed;\r
+    protected boolean removeAbandoned = false;\r
+    protected int removeAbandonedTimeout = 60;\r
+    protected boolean logAbandoned = false;\r
+    protected int loginTimeout = 10000;\r
+    protected String name = "Filip Connection Pool["+(poolCounter++)+"]";\r
+    protected String password;\r
+    protected String username;\r
+    protected long validationInterval = 30000;\r
+    protected boolean jmxEnabled = true;\r
+    protected String initSQL;\r
+    protected boolean testOnConnect =false;\r
+    private String jdbcInterceptors=null;\r
+\r
+    public boolean isAccessToUnderlyingConnectionAllowed() {\r
+        return accessToUnderlyingConnectionAllowed;\r
+    }\r
+\r
+    public String getConnectionProperties() {\r
+        return connectionProperties;\r
+    }\r
+\r
+    public Properties getDbProperties() {\r
+        return dbProperties;\r
+    }\r
+\r
+    public boolean isDefaultAutoCommit() {\r
+        return defaultAutoCommit;\r
+    }\r
+\r
+    public String getDefaultCatalog() {\r
+        return defaultCatalog;\r
+    }\r
+\r
+    public boolean isDefaultReadOnly() {\r
+        return defaultReadOnly;\r
+    }\r
+\r
+    public int getDefaultTransactionIsolation() {\r
+        return defaultTransactionIsolation;\r
+    }\r
+\r
+    public String getDriverClassName() {\r
+        return driverClassName;\r
+    }\r
+\r
+    public int getInitialSize() {\r
+        return initialSize;\r
+    }\r
+\r
+    public boolean isLogAbandoned() {\r
+        return logAbandoned;\r
+    }\r
+\r
+    public int getLoginTimeout() {\r
+        return loginTimeout;\r
+    }\r
+\r
+    public int getMaxActive() {\r
+        return maxActive;\r
+    }\r
+\r
+    public int getMaxIdle() {\r
+        return maxIdle;\r
+    }\r
+\r
+    public int getMaxWait() {\r
+        return maxWait;\r
+    }\r
+\r
+    public int getMinEvictableIdleTimeMillis() {\r
+        return minEvictableIdleTimeMillis;\r
+    }\r
+\r
+    public int getMinIdle() {\r
+        return minIdle;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public int getNumTestsPerEvictionRun() {\r
+        return numTestsPerEvictionRun;\r
+    }\r
+\r
+    public String getPassword() {\r
+        return password;\r
+    }\r
+\r
+    public String getPoolName() {\r
+        return getName();\r
+    }\r
+\r
+    public boolean isRemoveAbandoned() {\r
+        return removeAbandoned;\r
+    }\r
+\r
+    public int getRemoveAbandonedTimeout() {\r
+        return removeAbandonedTimeout;\r
+    }\r
+\r
+    public boolean isTestOnBorrow() {\r
+        return testOnBorrow;\r
+    }\r
+\r
+    public boolean isTestOnReturn() {\r
+        return testOnReturn;\r
+    }\r
+\r
+    public boolean isTestWhileIdle() {\r
+        return testWhileIdle;\r
+    }\r
+\r
+    public int getTimeBetweenEvictionRunsMillis() {\r
+        return timeBetweenEvictionRunsMillis;\r
+    }\r
+\r
+    public String getUrl() {\r
+        return url;\r
+    }\r
+\r
+    public String getUsername() {\r
+        return username;\r
+    }\r
+\r
+    public String getValidationQuery() {\r
+        return validationQuery;\r
+    }\r
+\r
+    public long getValidationInterval() {\r
+        return validationInterval;\r
+    }\r
+\r
+    public String getInitSQL() {\r
+        return initSQL;\r
+    }\r
+\r
+    public boolean isTestOnConnect() {\r
+        return testOnConnect;\r
+    }\r
+\r
+    public String getJdbcInterceptors() {\r
+        return jdbcInterceptors;\r
+    }\r
+\r
+    public String[] getJdbcInterceptorsAsArray() {\r
+        if (jdbcInterceptors==null) return new String[0];\r
+        else {\r
+            return jdbcInterceptors.split(";");\r
+        }\r
+    }\r
+\r
+    public void setAccessToUnderlyingConnectionAllowed(boolean\r
+        accessToUnderlyingConnectionAllowed) {\r
+        this.accessToUnderlyingConnectionAllowed =\r
+            accessToUnderlyingConnectionAllowed;\r
+    }\r
+\r
+    public void setConnectionProperties(String connectionProperties) {\r
+        this.connectionProperties = connectionProperties;\r
+    }\r
+\r
+    public void setDbProperties(Properties dbProperties) {\r
+        this.dbProperties = dbProperties;\r
+    }\r
+\r
+    public void setDefaultAutoCommit(Boolean defaultAutoCommit) {\r
+        this.defaultAutoCommit = defaultAutoCommit;\r
+    }\r
+\r
+    public void setDefaultCatalog(String defaultCatalog) {\r
+        this.defaultCatalog = defaultCatalog;\r
+    }\r
+\r
+    public void setDefaultReadOnly(Boolean defaultReadOnly) {\r
+        this.defaultReadOnly = defaultReadOnly;\r
+    }\r
+\r
+    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {\r
+        this.defaultTransactionIsolation = defaultTransactionIsolation;\r
+    }\r
+\r
+    public void setDriverClassName(String driverClassName) {\r
+        this.driverClassName = driverClassName;\r
+    }\r
+\r
+    public void setInitialSize(int initialSize) {\r
+        this.initialSize = initialSize;\r
+    }\r
+\r
+    public void setLogAbandoned(boolean logAbandoned) {\r
+        this.logAbandoned = logAbandoned;\r
+    }\r
+\r
+    public void setLoginTimeout(int loginTimeout) {\r
+        this.loginTimeout = loginTimeout;\r
+    }\r
+\r
+    public void setMaxActive(int maxActive) {\r
+        this.maxActive = maxActive;\r
+    }\r
+\r
+    public void setMaxIdle(int maxIdle) {\r
+        this.maxIdle = maxIdle;\r
+    }\r
+\r
+    public void setMaxWait(int maxWait) {\r
+        this.maxWait = maxWait;\r
+    }\r
+\r
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {\r
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;\r
+    }\r
+\r
+    public void setMinIdle(int minIdle) {\r
+        this.minIdle = minIdle;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {\r
+        this.numTestsPerEvictionRun = numTestsPerEvictionRun;\r
+    }\r
+\r
+    public void setPassword(String password) {\r
+        this.password = password;\r
+    }\r
+\r
+    public void setRemoveAbandoned(boolean removeAbandoned) {\r
+        this.removeAbandoned = removeAbandoned;\r
+    }\r
+\r
+    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {\r
+        this.removeAbandonedTimeout = removeAbandonedTimeout;\r
+    }\r
+\r
+    public void setTestOnBorrow(boolean testOnBorrow) {\r
+        this.testOnBorrow = testOnBorrow;\r
+    }\r
+\r
+    public void setTestWhileIdle(boolean testWhileIdle) {\r
+        this.testWhileIdle = testWhileIdle;\r
+    }\r
+\r
+    public void setTestOnReturn(boolean testOnReturn) {\r
+        this.testOnReturn = testOnReturn;\r
+    }\r
+\r
+    public void setTimeBetweenEvictionRunsMillis(int\r
+                                                 timeBetweenEvictionRunsMillis) {\r
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;\r
+    }\r
+\r
+    public void setUrl(String url) {\r
+        this.url = url;\r
+    }\r
+\r
+    public void setUsername(String username) {\r
+        this.username = username;\r
+    }\r
+\r
+    public void setValidationInterval(long validationInterval) {\r
+        this.validationInterval = validationInterval;\r
+    }\r
+\r
+    public void setValidationQuery(String validationQuery) {\r
+        this.validationQuery = validationQuery;\r
+    }\r
+\r
+    public void setInitSQL(String initSQL) {\r
+        this.initSQL = initSQL;\r
+    }\r
+\r
+    public void setTestOnConnect(boolean testOnConnect) {\r
+        this.testOnConnect = testOnConnect;\r
+    }\r
+\r
+    public void setJdbcInterceptors(String jdbcInterceptors) {\r
+        this.jdbcInterceptors = jdbcInterceptors;\r
+    }\r
+\r
+    public String toString() {\r
+        StringBuffer buf = new StringBuffer("ConnectionPool[");\r
+        try {\r
+            String[] fields = DataSourceFactory.ALL_PROPERTIES;\r
+            for (int i=0; i<fields.length; i++) {\r
+                final String[] prefix = new String[] {"get","is"};\r
+                for (int j=0; j<prefix.length; j++) {\r
+\r
+                    String name = prefix[j] + fields[i].substring(0, 1).toUpperCase() +\r
+                                  fields[i].substring(1);\r
+                    Method m = null;\r
+                    try {\r
+                        m = getClass().getMethod(name);\r
+                    }catch (NoSuchMethodException nm) {\r
+                        continue;\r
+                    }\r
+                    buf.append(fields[i]);\r
+                    buf.append("=");\r
+                    buf.append(m.invoke(this, new Object[0]));\r
+                    buf.append("; ");\r
+                    break;\r
+                }\r
+            }\r
+        }catch (Exception x) {\r
+            //shouldn;t happen\r
+            x.printStackTrace();\r
+        }\r
+        return buf.toString();\r
+    }\r
+\r
+    public static int getPoolCounter() {\r
+        return poolCounter;\r
+    }\r
+\r
+    public boolean isJmxEnabled() {\r
+        return jmxEnabled;\r
+    }\r
+\r
+    public void setJmxEnabled(boolean jmxEnabled) {\r
+        this.jmxEnabled = jmxEnabled;\r
+    }\r
+\r
+    public Boolean getDefaultAutoCommit() {\r
+        return defaultAutoCommit;\r
+    }\r
+\r
+    public Boolean getDefaultReadOnly() {\r
+        return defaultReadOnly;\r
+    }\r
+    \r
+    public boolean isPoolSweeperEnabled() {\r
+        boolean result = getTimeBetweenEvictionRunsMillis()>0;\r
+        result = result && (isRemoveAbandoned() && getRemoveAbandonedTimeout()>0);\r
+        result = result && (isTestWhileIdle() && getValidationQuery()!=null);\r
+        return result;\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
new file mode 100644 (file)
index 0000000..7998391
--- /dev/null
@@ -0,0 +1,294 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+\r
+import java.lang.ref.WeakReference;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.concurrent.locks.ReentrantReadWriteLock;\r
+\r
+import org.apache.juli.logging.Log;\r
+import org.apache.juli.logging.LogFactory;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class PooledConnection {\r
+\r
+    public static final int VALIDATE_BORROW = 1;\r
+    public static final int VALIDATE_RETURN = 2;\r
+    public static final int VALIDATE_IDLE = 3;\r
+    public static final int VALIDATE_INIT = 4;\r
+\r
+    protected static Log log = LogFactory.getLog(PooledConnection.class);\r
+    protected static volatile int counter = 1;\r
+\r
+    protected PoolProperties poolProperties;\r
+    protected java.sql.Connection connection;\r
+    protected String abandonTrace = null;\r
+    protected long timestamp;\r
+    protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);\r
+    protected boolean discarded = false;\r
+    protected long lastValidated = System.currentTimeMillis();\r
+    protected int instanceCount = 0;\r
+    protected ConnectionPool parent;\r
+\r
+    protected WeakReference<JdbcInterceptor> handler = null;\r
+\r
+    public PooledConnection(PoolProperties prop, ConnectionPool parent) throws SQLException {\r
+        instanceCount = counter++;\r
+        poolProperties = prop;\r
+        this.parent = parent;\r
+    }\r
+\r
+    protected void connect() throws SQLException {\r
+        if (connection != null) {\r
+            try {\r
+                this.disconnect();\r
+            } catch (Exception x) {\r
+                log.error("Unable to disconnect previous connection.", x);\r
+            } //catch\r
+        } //end if\r
+        java.sql.Driver driver = null;\r
+        try {\r
+            driver = (java.sql.Driver) Class.forName(poolProperties.getDriverClassName(),\r
+                                                     true, PooledConnection.class.getClassLoader()).newInstance();\r
+        } catch (java.lang.Exception cn) {\r
+            log.error("Unable to instantiate JDBC driver.", cn);\r
+            throw new SQLException(cn.getMessage());\r
+        }\r
+        String driverURL = poolProperties.getUrl();\r
+        String usr = poolProperties.getUsername();\r
+        String pwd = poolProperties.getPassword();\r
+        poolProperties.getDbProperties().setProperty("user", usr);\r
+        poolProperties.getDbProperties().setProperty("password", pwd);\r
+        connection = driver.connect(driverURL, poolProperties.getDbProperties());\r
+        //set up the default state\r
+        if (poolProperties.getDefaultReadOnly()!=null) connection.setReadOnly(poolProperties.getDefaultReadOnly().booleanValue());\r
+        if (poolProperties.getDefaultAutoCommit()!=null) connection.setAutoCommit(poolProperties.getDefaultAutoCommit().booleanValue());\r
+        if (poolProperties.getDefaultCatalog()!=null) connection.setCatalog(poolProperties.getDefaultCatalog());\r
+        if (poolProperties.getDefaultTransactionIsolation()!=DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION) connection.setTransactionIsolation(poolProperties.getDefaultTransactionIsolation());\r
+        \r
+        this.discarded = false;\r
+    }\r
+\r
+    protected void reconnect() throws SQLException {\r
+        this.disconnect();\r
+        this.connect();\r
+    } //reconnect\r
+\r
+    protected synchronized void disconnect() throws SQLException {\r
+        if (isDiscarded()) {\r
+            return;\r
+        }\r
+        setDiscarded(true);\r
+        if (connection != null) {\r
+            connection.close();\r
+        }\r
+        connection = null;\r
+        parent.finalize(this);\r
+    }\r
+\r
+\r
+//============================================================================\r
+//             com.filip.util.IPoolObject methods\r
+//============================================================================\r
+\r
+    public long getAbandonTimeout() {\r
+        if (poolProperties.getRemoveAbandonedTimeout() <= 0) {\r
+            return Long.MAX_VALUE;\r
+        } else {\r
+            return poolProperties.getRemoveAbandonedTimeout()*1000;\r
+        } //end if\r
+    }\r
+\r
+    public boolean abandon() {\r
+        try {\r
+            disconnect();\r
+        } catch (SQLException x) {\r
+            log.error("", x);\r
+        } //catch\r
+        return false;\r
+    }\r
+\r
+    protected boolean doValidate(int action) {\r
+        if (action == PooledConnection.VALIDATE_BORROW &&\r
+            poolProperties.isTestOnBorrow())\r
+            return true;\r
+        else if (action == PooledConnection.VALIDATE_RETURN &&\r
+                 poolProperties.isTestOnReturn())\r
+            return true;\r
+        else if (action == PooledConnection.VALIDATE_IDLE &&\r
+                 poolProperties.isTestWhileIdle())\r
+            return true;\r
+        else if (action == PooledConnection.VALIDATE_INIT &&\r
+                 poolProperties.isTestOnConnect())\r
+            return true;\r
+        else if (action == PooledConnection.VALIDATE_INIT &&\r
+                 poolProperties.getInitSQL()!=null)\r
+           return true;\r
+        else\r
+            return false;\r
+    }\r
+\r
+    /**Returns true if the object is still valid. if not\r
+     * the pool will call the getExpiredAction() and follow up with one\r
+     * of the four expired methods\r
+     */\r
+    public boolean validate(int validateAction) {\r
+        return validate(validateAction,null);\r
+    }\r
+\r
+    public boolean validate(int validateAction,String sql) {\r
+        if (!doValidate(validateAction)) {\r
+            //no validation required, no init sql and props not set\r
+            return true;\r
+        }\r
+\r
+        String query = (VALIDATE_INIT==validateAction && (poolProperties.getInitSQL()!=null))?poolProperties.getInitSQL():sql;\r
+\r
+        if (query==null) query = poolProperties.getValidationQuery();\r
+\r
+        if (query == null) {\r
+            //no validation possible\r
+            return true;\r
+        }\r
+        long now = System.currentTimeMillis();\r
+        if (this.poolProperties.getValidationInterval() > 0 &&\r
+            (now - this.lastValidated) <\r
+            this.poolProperties.getValidationInterval()) {\r
+            return true;\r
+        }\r
+        try {\r
+            Statement stmt = connection.createStatement();\r
+            boolean exec = stmt.execute(query);\r
+            stmt.close();\r
+            this.lastValidated = now;\r
+            return true;\r
+        } catch (Exception ignore) {\r
+            if (log.isDebugEnabled())\r
+                log.debug("Unable to validate object:",ignore);\r
+        }\r
+        return false;\r
+    } //validate\r
+\r
+    /**\r
+     * The time limit for how long the object\r
+     * can remain unused before it is released\r
+     */\r
+    public long getReleaseTime() {\r
+        return this.poolProperties.getMinEvictableIdleTimeMillis();\r
+    }\r
+\r
+    /**\r
+     * This method is called if (Now - timeCheckedIn > getReleaseTime())\r
+     */\r
+    public void release() {\r
+        try {\r
+            disconnect();\r
+        } catch (SQLException x) {\r
+            //TODO\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * The pool will set the stack trace when it is check out and\r
+     * checked in\r
+     */\r
+\r
+    public void setStackTrace(String trace) {\r
+        abandonTrace = trace;\r
+    }\r
+\r
+    public String getStackTrace() {\r
+        return abandonTrace;\r
+    }\r
+\r
+    public void setTimestamp(long timestamp) {\r
+        this.timestamp = timestamp;\r
+    }\r
+\r
+    public void setDiscarded(boolean discarded) {\r
+        if (this.discarded && !discarded) throw new IllegalStateException("Unable to change the state once the connection has been discarded");\r
+        this.discarded = discarded;\r
+    }\r
+\r
+    public void setLastValidated(long lastValidated) {\r
+        this.lastValidated = lastValidated;\r
+    }\r
+\r
+    public void setPoolProperties(PoolProperties poolProperties) {\r
+        this.poolProperties = poolProperties;\r
+    }\r
+\r
+    public long getTimestamp() {\r
+        return timestamp;\r
+    }\r
+\r
+    public boolean isDiscarded() {\r
+        return discarded;\r
+    }\r
+\r
+    public long getLastValidated() {\r
+        return lastValidated;\r
+    }\r
+\r
+    public PoolProperties getPoolProperties() {\r
+        return poolProperties;\r
+    }\r
+\r
+    public void lock() {\r
+        if (this.poolProperties.isPoolSweeperEnabled()) {\r
+            //optimized, only use a lock when there is concurrency\r
+            lock.writeLock().lock();\r
+        }\r
+    }\r
+\r
+    public void unlock() {\r
+        if (this.poolProperties.isPoolSweeperEnabled()) {\r
+          //optimized, only use a lock when there is concurrency\r
+            lock.writeLock().unlock();\r
+        }\r
+    }\r
+\r
+    public java.sql.Connection getConnection() {\r
+        return this.connection;\r
+    }\r
+\r
+    public JdbcInterceptor getHandler() {\r
+        return (handler!=null)?handler.get():null;\r
+    }\r
+\r
+    public void setHandler(JdbcInterceptor handler) {\r
+        if (handler==null) {\r
+            if (this.handler!=null) this.handler.clear();\r
+        } else if (this.handler==null) {\r
+            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
+        } else if (this.handler.get()==null) {\r
+            this.handler.clear();\r
+            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
+        } else if (this.handler.get()!=handler) {\r
+            this.handler.clear();\r
+            this.handler = new WeakReference<JdbcInterceptor>(handler);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java
new file mode 100644 (file)
index 0000000..9a66536
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool;\r
+\r
+import java.lang.reflect.Method;\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+/**\r
+ * @author Filip Hanik\r
+ */\r
+public class ProxyConnection extends JdbcInterceptor {\r
+\r
+    protected PooledConnection connection = null;\r
+\r
+    protected ConnectionPool pool = null;\r
+\r
+    public PooledConnection getConnection() {\r
+        return connection;\r
+    }\r
+\r
+    public void setConnection(PooledConnection connection) {\r
+        this.connection = connection;\r
+    }\r
+\r
+    public ConnectionPool getPool() {\r
+        return pool;\r
+    }\r
+\r
+    public void setPool(ConnectionPool pool) {\r
+        this.pool = pool;\r
+    }\r
+\r
+    protected ProxyConnection(ConnectionPool parent, PooledConnection con) throws SQLException {\r
+        pool = parent;\r
+        connection = con;\r
+    }\r
+\r
+    public void reset(ConnectionPool parent, PooledConnection con) {\r
+        this.pool = parent;\r
+        this.connection = con;\r
+    }\r
+\r
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
+        return (iface.isInstance(connection.getConnection()));\r
+    }\r
+\r
+\r
+    public Object unwrap(Class iface) throws SQLException {\r
+        if (isWrapperFor(iface)) {\r
+            return connection.getConnection();\r
+        } else {\r
+            throw new SQLException("Not a wrapper of "+iface.getName());\r
+        }\r
+    }\r
+\r
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+        if (isClosed()) throw new SQLException("Connection has already been closed.");\r
+        if (CLOSE_VAL==method.getName()) {\r
+            PooledConnection poolc = this.connection;\r
+            this.connection = null;\r
+            pool.returnConnection(poolc);\r
+            return null;\r
+        }\r
+        return method.invoke(connection.getConnection(),args);\r
+    }\r
+\r
+    public boolean isClosed() {\r
+        return connection==null || connection.isDiscarded();\r
+    }\r
+\r
+    public PooledConnection getDelegateConnection() {\r
+        return connection;\r
+    }\r
+\r
+    public ConnectionPool getParentPool() {\r
+        return pool;\r
+    }\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/ConnectionState.java
new file mode 100644 (file)
index 0000000..b30ae01
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool.interceptor;\r
+\r
+import java.lang.reflect.Method;\r
+\r
+import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
+import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
+import org.apache.tomcat.jdbc.pool.PooledConnection;\r
+\r
+/**\r
+ * Interceptor that keep track of connection state to avoid roundtrips to the database\r
+ * @author fhanik\r
+ *\r
+ */\r
+\r
+public class ConnectionState extends JdbcInterceptor  {\r
+\r
+    protected final String[] readState = {"getAutoCommit","getTransactionIsolation","isReadOnly"};\r
+    protected final String[] writeState = {"setAutoCommit","setTransactionIsolation","setReadOnly"};\r
+\r
+    protected Boolean autoCommit = null;\r
+    protected Integer transactionIsolation = null;\r
+    protected Boolean readOnly = null;\r
+\r
+    public void reset(ConnectionPool parent, PooledConnection con) {\r
+        autoCommit = null;\r
+        transactionIsolation = null;\r
+        readOnly = null;\r
+    }\r
+\r
+    @Override\r
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+        String name = method.getName();\r
+        boolean read = false;\r
+        int index = -1;\r
+        for (int i=0; (!read) && i<readState.length; i++) {\r
+            read = name==readState[i];\r
+            if (read) index = i;\r
+        }\r
+        boolean write = false;\r
+        for (int i=0; (!write) && (!read) && i<writeState.length; i++) {\r
+            write = name==writeState[i];\r
+            if (write) index = i;\r
+        }\r
+        Object result = null;\r
+        if (read) {\r
+            switch (index) {\r
+                case 0:{result = autoCommit; break;}\r
+                case 1:{result = transactionIsolation; break;}\r
+                case 2:{result = readOnly; break;}\r
+                default: result = null;\r
+            }\r
+            //return cached result, if we have it\r
+            if (result!=null) return result;\r
+        }\r
+\r
+        result = super.invoke(proxy, method, args);\r
+        if (read || write) {\r
+            switch (index) {\r
+                case 0:{autoCommit = (Boolean) (read?result:args[0]); break;}\r
+                case 1:{transactionIsolation = (Integer)(read?result:args[0]); break;}\r
+                case 2:{readOnly = (Boolean)(read?result:args[0]); break;}\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
new file mode 100644 (file)
index 0000000..aa3efab
--- /dev/null
@@ -0,0 +1,107 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool.interceptor;\r
+\r
+import java.lang.reflect.InvocationHandler;\r
+import java.lang.reflect.Method;\r
+import java.lang.reflect.Proxy;\r
+import java.sql.CallableStatement;\r
+import java.sql.SQLException;\r
+\r
+import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
+import org.apache.tomcat.jdbc.pool.PooledConnection;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class SlowQueryReport extends JdbcInterceptor {\r
+    protected final String[] statements = {"createStatement","prepareStatement","prepareCall"};\r
+    protected final String[] executes = {"execute","executeQuery","executeUpdate","executeBatch"};\r
+\r
+    public SlowQueryReport() {\r
+        super();\r
+    }\r
+\r
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+        boolean process = false;\r
+        process = process(statements, method, process);\r
+        if (process) {\r
+            Object statement = super.invoke(proxy,method,args);\r
+            CallableStatement measuredStatement =\r
+                (CallableStatement)Proxy.newProxyInstance(SlowQueryReport.class.getClassLoader(),\r
+                    new Class[] {java.sql.CallableStatement.class,\r
+                                 java.sql.PreparedStatement.class,\r
+                                 java.sql.Statement.class},\r
+                    new StatementProxy(statement, args));\r
+\r
+            return measuredStatement;\r
+        } else {\r
+            return super.invoke(proxy,method,args);\r
+        }\r
+    }\r
+\r
+    protected boolean process(String[] names, Method method, boolean process) {\r
+        for (int i=0; (!process) && i<names.length; i++) {\r
+            process = (method.getName()==names[i]);\r
+        }\r
+        return process;\r
+    }\r
+\r
+    protected class StatementProxy implements InvocationHandler {\r
+        protected Object parent;\r
+        protected Object[] args;\r
+        public StatementProxy(Object parent, Object[] args) {\r
+            this.parent = parent;\r
+            this.args = args;\r
+        }\r
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\r
+            if (this.parent == null ) throw new SQLException("Statement has been closed.");\r
+            boolean process = false;\r
+            process = process(executes, method, process);\r
+            long start = (process)?System.currentTimeMillis():0;\r
+            //execute the query\r
+            Object result =  method.invoke(parent,args);\r
+            long delta = (process)?(System.currentTimeMillis()-start):0;\r
+            if (delta>10) {\r
+                StringBuffer out = new StringBuffer("\n\tType:");\r
+                out.append(parent.getClass().getName());\r
+                out.append("\n\tCreate/Prepare args:");\r
+                for (int i=0; this.args!=null && i<this.args.length;i++) {\r
+                    out.append(this.args[i]!=null?this.args[i]:"null");\r
+                    out.append("; ");\r
+                }\r
+                out.append("\n\tExecute args:");\r
+                for (int i=0; args!=null && i<args.length;i++) {\r
+                    out.append(args[i]!=null?args[i]:"null");\r
+                    out.append("; ");\r
+                }\r
+                System.out.println("Slow query:"+out+"\nTime to execute:"+(delta)+" ms.");\r
+            }\r
+            if (JdbcInterceptor.CLOSE_VAL==method.getName()) {\r
+                this.parent = null;\r
+                this.args = null;\r
+            }\r
+            return result;\r
+        }\r
+    }\r
+\r
+    public void reset(ConnectionPool parent, PooledConnection con) {\r
+\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
new file mode 100644 (file)
index 0000000..f8a63ec
--- /dev/null
@@ -0,0 +1,171 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool.jmx;\r
+/**\r
+ * @author Filip Hanik\r
+ */\r
+import java.util.Properties;\r
+\r
+import javax.management.DynamicMBean;\r
+\r
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
+\r
+public class ConnectionPool implements ConnectionPoolMBean  {\r
+    protected org.apache.tomcat.jdbc.pool.ConnectionPool pool = null;\r
+\r
+    public ConnectionPool(org.apache.tomcat.jdbc.pool.ConnectionPool pool) {\r
+        this.pool = pool;\r
+    }\r
+\r
+    public org.apache.tomcat.jdbc.pool.ConnectionPool getPool() {\r
+        return pool;\r
+    }\r
+\r
+    //=================================================================\r
+    //       POOL STATS\r
+    //=================================================================\r
+\r
+    public int getSize() {\r
+        return pool.getSize();\r
+    }\r
+\r
+    public int getIdle() {\r
+        return pool.getIdle();\r
+    }\r
+\r
+    public int getActive() {\r
+        return pool.getActive();\r
+    }\r
+    \r
+    public boolean isPoolSweeperEnabled() {\r
+        return pool.getPoolProperties().isPoolSweeperEnabled();\r
+    }\r
+\r
+    //=================================================================\r
+    //       POOL OPERATIONS\r
+    //=================================================================\r
+    public void checkIdle() {\r
+        pool.checkIdle();\r
+    }\r
+\r
+    public void checkAbandoned() {\r
+        pool.checkAbandoned();\r
+    }\r
+\r
+    public void testIdle() {\r
+        pool.testAllIdle();\r
+    }\r
+    //=================================================================\r
+    //       POOL PROPERTIES\r
+    //=================================================================\r
+    public Properties getDbProperties() {\r
+        return pool.getPoolProperties().getDbProperties();\r
+    }\r
+    public String getUrl() {\r
+        return pool.getPoolProperties().getUrl();\r
+    }\r
+    public String getDriverClassName() {\r
+        return pool.getPoolProperties().getDriverClassName();\r
+    }\r
+    public boolean isDefaultAutoCommit() {\r
+        return pool.getPoolProperties().isDefaultAutoCommit();\r
+    }\r
+    public boolean isDefaultReadOnly() {\r
+        return pool.getPoolProperties().isDefaultReadOnly();\r
+    }\r
+    public int getDefaultTransactionIsolation() {\r
+        return pool.getPoolProperties().getDefaultTransactionIsolation();\r
+    }\r
+    public String getConnectionProperties() {\r
+        return pool.getPoolProperties().getConnectionProperties();\r
+    }\r
+    public String getDefaultCatalog() {\r
+        return pool.getPoolProperties().getDefaultCatalog();\r
+    }\r
+    public int getInitialSize() {\r
+        return pool.getPoolProperties().getInitialSize();\r
+    }\r
+    public int getMaxActive() {\r
+        return pool.getPoolProperties().getMaxActive();\r
+    }\r
+    public int getMaxIdle() {\r
+        return pool.getPoolProperties().getMaxIdle();\r
+    }\r
+    public int getMinIdle() {\r
+        return pool.getPoolProperties().getMinIdle();\r
+    }\r
+    public int getMaxWait() {\r
+        return pool.getPoolProperties().getMaxWait();\r
+    }\r
+    public String getValidationQuery() {\r
+        return pool.getPoolProperties().getValidationQuery();\r
+    }\r
+    public boolean isTestOnBorrow() {\r
+        return pool.getPoolProperties().isTestOnBorrow();\r
+    }\r
+    public boolean isTestOnReturn() {\r
+        return pool.getPoolProperties().isTestOnReturn();\r
+    }\r
+    public boolean isTestWhileIdle() {\r
+        return pool.getPoolProperties().isTestWhileIdle();\r
+    }\r
+    public int getTimeBetweenEvictionRunsMillis() {\r
+        return pool.getPoolProperties().getTimeBetweenEvictionRunsMillis();\r
+    }\r
+    public int getNumTestsPerEvictionRun() {\r
+        return pool.getPoolProperties().getNumTestsPerEvictionRun();\r
+    }\r
+    public int getMinEvictableIdleTimeMillis() {\r
+        return pool.getPoolProperties().getMinEvictableIdleTimeMillis();\r
+    }\r
+    public boolean isAccessToUnderlyingConnectionAllowed() {\r
+        return pool.getPoolProperties().isAccessToUnderlyingConnectionAllowed();\r
+    }\r
+    public boolean isRemoveAbandoned() {\r
+        return pool.getPoolProperties().isRemoveAbandoned();\r
+    }\r
+    public int getRemoveAbandonedTimeout() {\r
+        return pool.getPoolProperties().getRemoveAbandonedTimeout();\r
+    }\r
+    public boolean isLogAbandoned() {\r
+        return pool.getPoolProperties().isLogAbandoned();\r
+    }\r
+    public int getLoginTimeout() {\r
+        return pool.getPoolProperties().getLoginTimeout();\r
+    }\r
+    public String getName() {\r
+        return pool.getPoolProperties().getName();\r
+    }\r
+    public String getPassword() {\r
+        return pool.getPoolProperties().getPassword();\r
+    }\r
+    public String getUsername() {\r
+        return pool.getPoolProperties().getUsername();\r
+    }\r
+    public long getValidationInterval() {\r
+        return pool.getPoolProperties().getValidationInterval();\r
+    }\r
+    public String getInitSQL() {\r
+        return pool.getPoolProperties().getInitSQL();\r
+    }\r
+    public boolean isTestOnConnect() {\r
+        return pool.getPoolProperties().isTestOnConnect();\r
+    }\r
+    public String getJdbcInterceptors() {\r
+        return pool.getPoolProperties().getJdbcInterceptors();\r
+    }\r
+\r
+}\r
diff --git a/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java b/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPoolMBean.java
new file mode 100644 (file)
index 0000000..053fc2d
--- /dev/null
@@ -0,0 +1,115 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.pool.jmx;\r
+\r
+import java.util.Properties;\r
+\r
+import javax.management.DynamicMBean;\r
+\r
+import org.apache.tomcat.jdbc.pool.ConnectionPool;\r
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;\r
+\r
+public interface ConnectionPoolMBean  {\r
+\r
+    //=================================================================\r
+    //       POOL STATS\r
+    //=================================================================\r
+\r
+    public int getSize();\r
+\r
+    public int getIdle();\r
+\r
+    public int getActive();\r
+    \r
+    public boolean isPoolSweeperEnabled();\r
+\r
+    //=================================================================\r
+    //       POOL OPERATIONS\r
+    //=================================================================\r
+    public void checkIdle();\r
+\r
+    public void checkAbandoned();\r
+\r
+    public void testIdle();\r
+\r
+    //=================================================================\r
+    //       POOL PROPERTIES\r
+    //=================================================================\r
+    public Properties getDbProperties();\r
+\r
+    public String getUrl();\r
+\r
+    public String getDriverClassName();\r
+\r
+    public boolean isDefaultAutoCommit();\r
+\r
+    public boolean isDefaultReadOnly();\r
+\r
+    public int getDefaultTransactionIsolation();\r
+\r
+    public String getConnectionProperties();\r
+\r
+    public String getDefaultCatalog();\r
+\r
+    public int getInitialSize();\r
+\r
+    public int getMaxActive();\r
+\r
+    public int getMaxIdle();\r
+\r
+    public int getMinIdle();\r
+\r
+    public int getMaxWait();\r
+\r
+    public String getValidationQuery();\r
+\r
+    public boolean isTestOnBorrow();\r
+\r
+    public boolean isTestOnReturn();\r
+\r
+    public boolean isTestWhileIdle();\r
+\r
+    public int getTimeBetweenEvictionRunsMillis();\r
+\r
+    public int getNumTestsPerEvictionRun();\r
+\r
+    public int getMinEvictableIdleTimeMillis();\r
+\r
+    public boolean isAccessToUnderlyingConnectionAllowed();\r
+\r
+    public boolean isRemoveAbandoned();\r
+\r
+    public int getRemoveAbandonedTimeout();\r
+\r
+    public boolean isLogAbandoned();\r
+\r
+    public int getLoginTimeout();\r
+\r
+    public String getName();\r
+\r
+    public String getPassword();\r
+\r
+    public String getUsername();\r
+\r
+    public long getValidationInterval();\r
+\r
+    public String getInitSQL();\r
+\r
+    public boolean isTestOnConnect();\r
+\r
+    public String getJdbcInterceptors();\r
+\r
+}\r
diff --git a/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java b/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java
new file mode 100644 (file)
index 0000000..7b115d7
--- /dev/null
@@ -0,0 +1,254 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.test;\r
+\r
+import java.util.concurrent.CountDownLatch;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+import java.sql.Connection;\r
+import java.sql.Statement;\r
+import java.sql.ResultSet;\r
+\r
+import javax.sql.DataSource;\r
+\r
+import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class CheckOutThreadTest extends DefaultTestCase {\r
+    public CheckOutThreadTest(String name) {\r
+        super(name);\r
+    }\r
+\r
+    CountDownLatch latch = null;\r
+\r
+    public void testDBCPThreads10Connections10() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.threadcount = 10;\r
+        this.transferProperties();\r
+        this.tDatasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-dbcp-"+i);\r
+            t.d = this.tDatasource;\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testDBCPThreads10Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testPoolThreads10Connections10() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.threadcount = 10;\r
+        this.transferProperties();\r
+        this.datasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-pool-"+i);\r
+            t.d = DataSourceFactory.getDataSource(this.datasource);\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testPoolThreads10Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testDBCPThreads20Connections10() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.threadcount = 20;\r
+        this.transferProperties();\r
+        this.tDatasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-dbcp-"+i);\r
+            t.d = this.tDatasource;\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testDBCPThreads20Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testPoolThreads20Connections10() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.threadcount = 20;\r
+        this.transferProperties();\r
+        this.datasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-pool-"+i);\r
+            t.d = DataSourceFactory.getDataSource(this.datasource);\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testPoolThreads20Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+\r
+    \r
+    public void testDBCPThreads10Connections10Validate() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
+        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
+        this.threadcount = 10;\r
+        this.transferProperties();\r
+        this.tDatasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-dbcp-validate-"+i);\r
+            t.d = this.tDatasource;\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testDBCPThreads10Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testPoolThreads10Connections10Validate() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
+        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
+        this.threadcount = 10;\r
+        this.transferProperties();\r
+        this.datasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-pool-validate-"+i);\r
+            t.d = DataSourceFactory.getDataSource(this.datasource);\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testPoolThreads10Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testDBCPThreads20Connections10Validate() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
+        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
+        this.threadcount = 20;\r
+        this.transferProperties();\r
+        this.tDatasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-dbcp-validate-"+i);\r
+            t.d = this.tDatasource;\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testDBCPThreads20Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    public void testPoolThreads10Connections20Validate() throws Exception {\r
+        init();\r
+        this.datasource.getPoolProperties().setMaxActive(10);\r
+        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
+        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
+        this.threadcount = 20;\r
+        this.transferProperties();\r
+        this.datasource.getConnection().close();\r
+        latch = new CountDownLatch(threadcount);\r
+        long start = System.currentTimeMillis();\r
+        for (int i=0; i<threadcount; i++) {\r
+            TestThread t = new TestThread();\r
+            t.setName("tomcat-pool-validate-"+i);\r
+            t.d = DataSourceFactory.getDataSource(this.datasource);\r
+            t.start();\r
+        }\r
+        latch.await();\r
+        long delta = System.currentTimeMillis() - start;\r
+        System.out.println("[testPoolThreads20Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
+        tearDown();\r
+    }\r
+\r
+    \r
+    public class TestThread extends Thread {\r
+        protected DataSource d;\r
+        \r
+        public void run() {\r
+            long max = -1, totalmax=0, totalcmax=0, cmax = -1, nroffetch = 0, totalruntime = 0;\r
+            try {\r
+                for (int i = 0; i < CheckOutThreadTest.this.iterations; i++) {\r
+                    long start = System.nanoTime();\r
+                    Connection con = null;\r
+                    try {\r
+                        con = d.getConnection();\r
+                        long delta = System.nanoTime() - start;\r
+                        totalmax += delta;\r
+                        max = Math.max(delta, max);\r
+                        nroffetch++;\r
+                    } finally {\r
+                        long cstart = System.nanoTime();\r
+                        if (con!=null) try {con.close();}catch(Exception x) {x.printStackTrace();}\r
+                        long cdelta = System.nanoTime() - cstart;\r
+                        totalcmax += cdelta;\r
+                        cmax = Math.max(cdelta, cmax);\r
+                    }\r
+                    totalruntime+=(System.nanoTime()-start);\r
+                }\r
+\r
+            } catch (Exception x) {\r
+                x.printStackTrace();\r
+            } finally {\r
+                CheckOutThreadTest.this.latch.countDown();\r
+            }\r
+            if (System.getProperty("print-thread-stats")!=null) {\r
+                System.out.println("["+getName()+"] "+\r
+                    "\n\tMax time to retrieve connection:"+(((float)max)/1000f/1000f)+" ms."+\r
+                    "\n\tTotal time to retrieve connection:"+(((float)totalmax)/1000f/1000f)+" ms."+\r
+                    "\n\tAverage time to retrieve connection:"+(((float)totalmax)/1000f/1000f)/(float)nroffetch+" ms."+\r
+                    "\n\tMax time to close connection:"+(((float)cmax)/1000f/1000f)+" ms."+\r
+                    "\n\tTotal time to close connection:"+(((float)totalcmax)/1000f/1000f)+" ms."+\r
+                    "\n\tAverage time to close connection:"+(((float)totalcmax)/1000f/1000f)/(float)nroffetch+" ms."+\r
+                    "\n\tRun time:"+(((float)totalruntime)/1000f/1000f)+" ms."+\r
+                    "\n\tNr of fetch:"+nroffetch);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultProperties.java b/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultProperties.java
new file mode 100644 (file)
index 0000000..692ab40
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.test;\r
+\r
+import java.util.Properties;\r
+\r
+import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
+import org.apache.tomcat.jdbc.pool.PoolProperties;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class DefaultProperties extends PoolProperties {\r
+    public DefaultProperties() {\r
+        dbProperties = new Properties();\r
+        url = "jdbc:mysql://localhost:3306/mysql?autoReconnect=true";\r
+        driverClassName = "com.mysql.jdbc.Driver";\r
+        password = "password";\r
+        username = "root";\r
+        defaultAutoCommit = true;\r
+        defaultReadOnly = false;\r
+        defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;\r
+        connectionProperties = null;\r
+        defaultCatalog = null;\r
+        initialSize = 10;\r
+        maxActive = 100;\r
+        maxIdle = initialSize;\r
+        minIdle = initialSize;\r
+        maxWait = 10000;\r
+        validationQuery = "SELECT 1";\r
+        testOnBorrow = true;\r
+        testOnReturn = false;\r
+        testWhileIdle = true;\r
+        timeBetweenEvictionRunsMillis = 5000;\r
+        numTestsPerEvictionRun = 0;\r
+        minEvictableIdleTimeMillis = 1000;\r
+        accessToUnderlyingConnectionAllowed = false;\r
+        removeAbandoned = true;\r
+        removeAbandonedTimeout = 5000;\r
+        logAbandoned = true;\r
+        loginTimeout = 0;\r
+        validationInterval = 0; //always validate\r
+        initSQL = null;\r
+        testOnConnect = false;;\r
+        dbProperties.setProperty("user",username);\r
+        dbProperties.setProperty("password",password);\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultTestCase.java b/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/DefaultTestCase.java
new file mode 100644 (file)
index 0000000..dafa966
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.test;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.Properties;\r
+\r
+import org.apache.tomcat.dbcp.dbcp.BasicDataSource;\r
+import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.tomcat.jdbc.pool.PoolProperties;\r
+import org.apache.tomcat.jdbc.pool.DataSourceProxy;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class DefaultTestCase extends TestCase {\r
+    protected DataSourceProxy datasource;\r
+    protected BasicDataSource tDatasource;\r
+    protected int threadcount = 10;\r
+    protected int iterations = 100000;\r
+    public DefaultTestCase(String name) {\r
+        super(name);\r
+    }\r
+\r
+    protected void init() throws Exception {\r
+        PoolProperties p = new DefaultProperties();\r
+        p.setJmxEnabled(false);\r
+        p.setTestWhileIdle(false);\r
+        p.setTestOnBorrow(false);\r
+        p.setTestOnReturn(false);\r
+        p.setValidationInterval(30000);\r
+        p.setTimeBetweenEvictionRunsMillis(30000);\r
+        p.setMaxActive(threadcount);\r
+        p.setInitialSize(threadcount);\r
+        p.setMaxWait(10000);\r
+        p.setRemoveAbandonedTimeout(10000);\r
+        p.setMinEvictableIdleTimeMillis(10000);\r
+        p.setMinIdle(threadcount);\r
+        p.setLogAbandoned(false);\r
+        p.setRemoveAbandoned(false);\r
+        datasource = new org.apache.tomcat.jdbc.pool.DataSourceProxy();\r
+        datasource.setPoolProperties(p);\r
+    }\r
+\r
+    protected void transferProperties() {\r
+        try {\r
+            BasicDataSourceFactory factory = new BasicDataSourceFactory();\r
+            Properties p = new Properties();\r
+\r
+            for (int i=0; i<this.ALL_PROPERTIES.length; i++) {\r
+                String name = "get" + Character.toUpperCase(ALL_PROPERTIES[i].charAt(0)) + ALL_PROPERTIES[i].substring(1);\r
+                String bname = "is" + name.substring(3);\r
+                Method get = null;\r
+                try {\r
+                    get = PoolProperties.class.getMethod(name, new Class[0]);\r
+                }catch (NoSuchMethodException x) {\r
+                    try {\r
+                    get = PoolProperties.class.getMethod(bname, new Class[0]);\r
+                    }catch (NoSuchMethodException x2) {\r
+                        System.err.println(x2.getMessage());\r
+                    }\r
+                }\r
+                   if (get!=null) {\r
+                       Object value = get.invoke(datasource.getPoolProperties(), new Object[0]);\r
+                       if (value!=null) {\r
+                           p.setProperty(ALL_PROPERTIES[i], value.toString());\r
+                       }\r
+                }\r
+            }\r
+            tDatasource = (BasicDataSource)factory.createDataSource(p);\r
+        }catch (Exception x) {\r
+            x.printStackTrace();\r
+        }\r
+    }\r
+\r
+\r
+    protected void tearDown() throws Exception {\r
+        datasource = null;\r
+        tDatasource = null;\r
+        System.gc();\r
+    }\r
+\r
+    private final static String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";\r
+    private final static String PROP_DEFAULTREADONLY = "defaultReadOnly";\r
+    private final static String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";\r
+    private final static String PROP_DEFAULTCATALOG = "defaultCatalog";\r
+    private final static String PROP_DRIVERCLASSNAME = "driverClassName";\r
+    private final static String PROP_MAXACTIVE = "maxActive";\r
+    private final static String PROP_MAXIDLE = "maxIdle";\r
+    private final static String PROP_MINIDLE = "minIdle";\r
+    private final static String PROP_INITIALSIZE = "initialSize";\r
+    private final static String PROP_MAXWAIT = "maxWait";\r
+    private final static String PROP_TESTONBORROW = "testOnBorrow";\r
+    private final static String PROP_TESTONRETURN = "testOnReturn";\r
+    private final static String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";\r
+    private final static String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";\r
+    private final static String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";\r
+    private final static String PROP_TESTWHILEIDLE = "testWhileIdle";\r
+    private final static String PROP_PASSWORD = "password";\r
+    private final static String PROP_URL = "url";\r
+    private final static String PROP_USERNAME = "username";\r
+    private final static String PROP_VALIDATIONQUERY = "validationQuery";\r
+    private final static String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";\r
+    private final static String PROP_REMOVEABANDONED = "removeAbandoned";\r
+    private final static String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";\r
+    private final static String PROP_LOGABANDONED = "logAbandoned";\r
+    private final static String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";\r
+    private final static String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";\r
+    private final static String PROP_CONNECTIONPROPERTIES = "connectionProperties";\r
+\r
+    private final static String[] ALL_PROPERTIES = {\r
+        PROP_DEFAULTAUTOCOMMIT,\r
+        PROP_DEFAULTREADONLY,\r
+        PROP_DEFAULTTRANSACTIONISOLATION,\r
+        PROP_DEFAULTCATALOG,\r
+        PROP_DRIVERCLASSNAME,\r
+        PROP_MAXACTIVE,\r
+        PROP_MAXIDLE,\r
+        PROP_MINIDLE,\r
+        PROP_INITIALSIZE,\r
+        PROP_MAXWAIT,\r
+        PROP_TESTONBORROW,\r
+        PROP_TESTONRETURN,\r
+        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,\r
+        PROP_NUMTESTSPEREVICTIONRUN,\r
+        PROP_MINEVICTABLEIDLETIMEMILLIS,\r
+        PROP_TESTWHILEIDLE,\r
+        PROP_PASSWORD,\r
+        PROP_URL,\r
+        PROP_USERNAME,\r
+        PROP_VALIDATIONQUERY,\r
+        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,\r
+        PROP_REMOVEABANDONED,\r
+        PROP_REMOVEABANDONEDTIMEOUT,\r
+        PROP_LOGABANDONED,\r
+        PROP_CONNECTIONPROPERTIES\r
+    };\r
+\r
+\r
+\r
+}\r
diff --git a/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestGCClose.java b/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestGCClose.java
new file mode 100644 (file)
index 0000000..6b75ac0
--- /dev/null
@@ -0,0 +1,35 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.test;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class TestGCClose extends DefaultTestCase {\r
+    public TestGCClose(String name) {\r
+        super(name);\r
+    }\r
+    \r
+    public void testGCStop() throws Exception {\r
+        init();\r
+        datasource.getConnection();\r
+        System.out.println("Got a connection, but didn't return it");\r
+        tearDown();\r
+        Thread.sleep(10000);\r
+    }\r
+}\r
diff --git a/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestTimeout.java b/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/TestTimeout.java
new file mode 100644 (file)
index 0000000..049f2a6
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.tomcat.jdbc.test;\r
+\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+/**\r
+ * @author Filip Hanik\r
+ * @version 1.0\r
+ */\r
+public class TestTimeout extends DefaultTestCase {\r
+    public TestTimeout(String name) {\r
+        super(name);\r
+    }\r
+\r
+    AtomicInteger counter = new AtomicInteger(0);\r
+\r
+    public void testCheckoutTimeout() throws Exception {\r
+        try {\r
+            init();\r
+            this.datasource.getPoolProperties().setTestWhileIdle(true);\r
+            this.datasource.getPoolProperties().setTestOnBorrow(false);\r
+            this.datasource.getPoolProperties().setTestOnReturn(false);\r
+            this.datasource.getPoolProperties().setValidationInterval(30000);\r
+            this.datasource.getPoolProperties().setTimeBetweenEvictionRunsMillis(1000);\r
+            this.datasource.getPoolProperties().setMaxActive(20);\r
+            this.datasource.getPoolProperties().setMaxWait(3000);\r
+            this.datasource.getPoolProperties().setRemoveAbandonedTimeout(5000);\r
+            this.datasource.getPoolProperties().setMinEvictableIdleTimeMillis(5000);\r
+            this.datasource.getPoolProperties().setMinIdle(5);\r
+            this.datasource.getPoolProperties().setLogAbandoned(true);\r
+            System.out.println("About to test connection pool:"+datasource);\r
+            for (int i = 0; i < 21; i++) {\r
+                long now = System.currentTimeMillis();\r
+                this.datasource.getConnection();\r
+                long delta = System.currentTimeMillis()-now;\r
+                System.out.println("Got connection #"+i+" in "+delta+" ms.");\r
+            }\r
+        } catch ( Exception x ) {\r
+            x.printStackTrace();\r
+        }finally {\r
+            Thread.sleep(20000);\r
+            tearDown();\r
+        }\r
+    }\r
+\r
+    public void testRemoveAbandoned() throws Exception {\r
+        try {\r
+            init();\r
+            this.datasource.getPoolProperties().setTestWhileIdle(true);\r
+            this.datasource.getPoolProperties().setTestOnBorrow(false);\r
+            this.datasource.getPoolProperties().setTestOnReturn(false);\r
+            this.datasource.getPoolProperties().setValidationInterval(30000);\r
+            this.datasource.getPoolProperties().setTimeBetweenEvictionRunsMillis(1000);\r
+            this.datasource.getPoolProperties().setMaxActive(20);\r
+            this.datasource.getPoolProperties().setMaxWait(3000);\r
+            this.datasource.getPoolProperties().setRemoveAbandonedTimeout(5000);\r
+            this.datasource.getPoolProperties().setMinEvictableIdleTimeMillis(5000);\r
+            this.datasource.getPoolProperties().setMinIdle(5);\r
+            this.datasource.getPoolProperties().setRemoveAbandoned(true);\r
+            this.datasource.getPoolProperties().setLogAbandoned(true);\r
+            System.out.println("About to test connection pool:"+datasource);\r
+            for (int i = 0; i < threadcount; i++) {\r
+                long now = System.currentTimeMillis();\r
+                this.datasource.getConnection();\r
+                long delta = System.currentTimeMillis()-now;\r
+                System.out.println("Got connection #"+i+" in "+delta+" ms.");\r
+            }\r
+        } catch ( Exception x ) {\r
+            x.printStackTrace();\r
+        }finally {\r
+            Thread.sleep(20000);\r
+            tearDown();\r
+        }\r
+    }\r
+\r
+\r
+}\r
diff --git a/test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java b/test/org/apache/tomcat/jdbc/test/CheckOutThreadTest.java
deleted file mode 100644 (file)
index 7b115d7..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.test;\r
-\r
-import java.util.concurrent.CountDownLatch;\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-import java.sql.Connection;\r
-import java.sql.Statement;\r
-import java.sql.ResultSet;\r
-\r
-import javax.sql.DataSource;\r
-\r
-import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class CheckOutThreadTest extends DefaultTestCase {\r
-    public CheckOutThreadTest(String name) {\r
-        super(name);\r
-    }\r
-\r
-    CountDownLatch latch = null;\r
-\r
-    public void testDBCPThreads10Connections10() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.threadcount = 10;\r
-        this.transferProperties();\r
-        this.tDatasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-dbcp-"+i);\r
-            t.d = this.tDatasource;\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testDBCPThreads10Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testPoolThreads10Connections10() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.threadcount = 10;\r
-        this.transferProperties();\r
-        this.datasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-pool-"+i);\r
-            t.d = DataSourceFactory.getDataSource(this.datasource);\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testPoolThreads10Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testDBCPThreads20Connections10() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.threadcount = 20;\r
-        this.transferProperties();\r
-        this.tDatasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-dbcp-"+i);\r
-            t.d = this.tDatasource;\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testDBCPThreads20Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testPoolThreads20Connections10() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.threadcount = 20;\r
-        this.transferProperties();\r
-        this.datasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-pool-"+i);\r
-            t.d = DataSourceFactory.getDataSource(this.datasource);\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testPoolThreads20Connections10]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-\r
-    \r
-    public void testDBCPThreads10Connections10Validate() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
-        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
-        this.threadcount = 10;\r
-        this.transferProperties();\r
-        this.tDatasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-dbcp-validate-"+i);\r
-            t.d = this.tDatasource;\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testDBCPThreads10Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testPoolThreads10Connections10Validate() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
-        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
-        this.threadcount = 10;\r
-        this.transferProperties();\r
-        this.datasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-pool-validate-"+i);\r
-            t.d = DataSourceFactory.getDataSource(this.datasource);\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testPoolThreads10Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testDBCPThreads20Connections10Validate() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
-        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
-        this.threadcount = 20;\r
-        this.transferProperties();\r
-        this.tDatasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-dbcp-validate-"+i);\r
-            t.d = this.tDatasource;\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testDBCPThreads20Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    public void testPoolThreads10Connections20Validate() throws Exception {\r
-        init();\r
-        this.datasource.getPoolProperties().setMaxActive(10);\r
-        this.datasource.getPoolProperties().setValidationQuery("SELECT 1");\r
-        this.datasource.getPoolProperties().setTestOnBorrow(true);\r
-        this.threadcount = 20;\r
-        this.transferProperties();\r
-        this.datasource.getConnection().close();\r
-        latch = new CountDownLatch(threadcount);\r
-        long start = System.currentTimeMillis();\r
-        for (int i=0; i<threadcount; i++) {\r
-            TestThread t = new TestThread();\r
-            t.setName("tomcat-pool-validate-"+i);\r
-            t.d = DataSourceFactory.getDataSource(this.datasource);\r
-            t.start();\r
-        }\r
-        latch.await();\r
-        long delta = System.currentTimeMillis() - start;\r
-        System.out.println("[testPoolThreads20Connections10Validate]Test complete:"+delta+" ms. Iterations:"+(threadcount*this.iterations));\r
-        tearDown();\r
-    }\r
-\r
-    \r
-    public class TestThread extends Thread {\r
-        protected DataSource d;\r
-        \r
-        public void run() {\r
-            long max = -1, totalmax=0, totalcmax=0, cmax = -1, nroffetch = 0, totalruntime = 0;\r
-            try {\r
-                for (int i = 0; i < CheckOutThreadTest.this.iterations; i++) {\r
-                    long start = System.nanoTime();\r
-                    Connection con = null;\r
-                    try {\r
-                        con = d.getConnection();\r
-                        long delta = System.nanoTime() - start;\r
-                        totalmax += delta;\r
-                        max = Math.max(delta, max);\r
-                        nroffetch++;\r
-                    } finally {\r
-                        long cstart = System.nanoTime();\r
-                        if (con!=null) try {con.close();}catch(Exception x) {x.printStackTrace();}\r
-                        long cdelta = System.nanoTime() - cstart;\r
-                        totalcmax += cdelta;\r
-                        cmax = Math.max(cdelta, cmax);\r
-                    }\r
-                    totalruntime+=(System.nanoTime()-start);\r
-                }\r
-\r
-            } catch (Exception x) {\r
-                x.printStackTrace();\r
-            } finally {\r
-                CheckOutThreadTest.this.latch.countDown();\r
-            }\r
-            if (System.getProperty("print-thread-stats")!=null) {\r
-                System.out.println("["+getName()+"] "+\r
-                    "\n\tMax time to retrieve connection:"+(((float)max)/1000f/1000f)+" ms."+\r
-                    "\n\tTotal time to retrieve connection:"+(((float)totalmax)/1000f/1000f)+" ms."+\r
-                    "\n\tAverage time to retrieve connection:"+(((float)totalmax)/1000f/1000f)/(float)nroffetch+" ms."+\r
-                    "\n\tMax time to close connection:"+(((float)cmax)/1000f/1000f)+" ms."+\r
-                    "\n\tTotal time to close connection:"+(((float)totalcmax)/1000f/1000f)+" ms."+\r
-                    "\n\tAverage time to close connection:"+(((float)totalcmax)/1000f/1000f)/(float)nroffetch+" ms."+\r
-                    "\n\tRun time:"+(((float)totalruntime)/1000f/1000f)+" ms."+\r
-                    "\n\tNr of fetch:"+nroffetch);\r
-            }\r
-        }\r
-    }\r
-}\r
diff --git a/test/org/apache/tomcat/jdbc/test/DefaultProperties.java b/test/org/apache/tomcat/jdbc/test/DefaultProperties.java
deleted file mode 100644 (file)
index 692ab40..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.test;\r
-\r
-import java.util.Properties;\r
-\r
-import org.apache.tomcat.jdbc.pool.DataSourceFactory;\r
-import org.apache.tomcat.jdbc.pool.PoolProperties;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class DefaultProperties extends PoolProperties {\r
-    public DefaultProperties() {\r
-        dbProperties = new Properties();\r
-        url = "jdbc:mysql://localhost:3306/mysql?autoReconnect=true";\r
-        driverClassName = "com.mysql.jdbc.Driver";\r
-        password = "password";\r
-        username = "root";\r
-        defaultAutoCommit = true;\r
-        defaultReadOnly = false;\r
-        defaultTransactionIsolation = DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION;\r
-        connectionProperties = null;\r
-        defaultCatalog = null;\r
-        initialSize = 10;\r
-        maxActive = 100;\r
-        maxIdle = initialSize;\r
-        minIdle = initialSize;\r
-        maxWait = 10000;\r
-        validationQuery = "SELECT 1";\r
-        testOnBorrow = true;\r
-        testOnReturn = false;\r
-        testWhileIdle = true;\r
-        timeBetweenEvictionRunsMillis = 5000;\r
-        numTestsPerEvictionRun = 0;\r
-        minEvictableIdleTimeMillis = 1000;\r
-        accessToUnderlyingConnectionAllowed = false;\r
-        removeAbandoned = true;\r
-        removeAbandonedTimeout = 5000;\r
-        logAbandoned = true;\r
-        loginTimeout = 0;\r
-        validationInterval = 0; //always validate\r
-        initSQL = null;\r
-        testOnConnect = false;;\r
-        dbProperties.setProperty("user",username);\r
-        dbProperties.setProperty("password",password);\r
-    }\r
-}\r
diff --git a/test/org/apache/tomcat/jdbc/test/DefaultTestCase.java b/test/org/apache/tomcat/jdbc/test/DefaultTestCase.java
deleted file mode 100644 (file)
index dafa966..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.test;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.Properties;\r
-\r
-import org.apache.tomcat.dbcp.dbcp.BasicDataSource;\r
-import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;\r
-\r
-import junit.framework.TestCase;\r
-import org.apache.tomcat.jdbc.pool.PoolProperties;\r
-import org.apache.tomcat.jdbc.pool.DataSourceProxy;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class DefaultTestCase extends TestCase {\r
-    protected DataSourceProxy datasource;\r
-    protected BasicDataSource tDatasource;\r
-    protected int threadcount = 10;\r
-    protected int iterations = 100000;\r
-    public DefaultTestCase(String name) {\r
-        super(name);\r
-    }\r
-\r
-    protected void init() throws Exception {\r
-        PoolProperties p = new DefaultProperties();\r
-        p.setJmxEnabled(false);\r
-        p.setTestWhileIdle(false);\r
-        p.setTestOnBorrow(false);\r
-        p.setTestOnReturn(false);\r
-        p.setValidationInterval(30000);\r
-        p.setTimeBetweenEvictionRunsMillis(30000);\r
-        p.setMaxActive(threadcount);\r
-        p.setInitialSize(threadcount);\r
-        p.setMaxWait(10000);\r
-        p.setRemoveAbandonedTimeout(10000);\r
-        p.setMinEvictableIdleTimeMillis(10000);\r
-        p.setMinIdle(threadcount);\r
-        p.setLogAbandoned(false);\r
-        p.setRemoveAbandoned(false);\r
-        datasource = new org.apache.tomcat.jdbc.pool.DataSourceProxy();\r
-        datasource.setPoolProperties(p);\r
-    }\r
-\r
-    protected void transferProperties() {\r
-        try {\r
-            BasicDataSourceFactory factory = new BasicDataSourceFactory();\r
-            Properties p = new Properties();\r
-\r
-            for (int i=0; i<this.ALL_PROPERTIES.length; i++) {\r
-                String name = "get" + Character.toUpperCase(ALL_PROPERTIES[i].charAt(0)) + ALL_PROPERTIES[i].substring(1);\r
-                String bname = "is" + name.substring(3);\r
-                Method get = null;\r
-                try {\r
-                    get = PoolProperties.class.getMethod(name, new Class[0]);\r
-                }catch (NoSuchMethodException x) {\r
-                    try {\r
-                    get = PoolProperties.class.getMethod(bname, new Class[0]);\r
-                    }catch (NoSuchMethodException x2) {\r
-                        System.err.println(x2.getMessage());\r
-                    }\r
-                }\r
-                   if (get!=null) {\r
-                       Object value = get.invoke(datasource.getPoolProperties(), new Object[0]);\r
-                       if (value!=null) {\r
-                           p.setProperty(ALL_PROPERTIES[i], value.toString());\r
-                       }\r
-                }\r
-            }\r
-            tDatasource = (BasicDataSource)factory.createDataSource(p);\r
-        }catch (Exception x) {\r
-            x.printStackTrace();\r
-        }\r
-    }\r
-\r
-\r
-    protected void tearDown() throws Exception {\r
-        datasource = null;\r
-        tDatasource = null;\r
-        System.gc();\r
-    }\r
-\r
-    private final static String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";\r
-    private final static String PROP_DEFAULTREADONLY = "defaultReadOnly";\r
-    private final static String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";\r
-    private final static String PROP_DEFAULTCATALOG = "defaultCatalog";\r
-    private final static String PROP_DRIVERCLASSNAME = "driverClassName";\r
-    private final static String PROP_MAXACTIVE = "maxActive";\r
-    private final static String PROP_MAXIDLE = "maxIdle";\r
-    private final static String PROP_MINIDLE = "minIdle";\r
-    private final static String PROP_INITIALSIZE = "initialSize";\r
-    private final static String PROP_MAXWAIT = "maxWait";\r
-    private final static String PROP_TESTONBORROW = "testOnBorrow";\r
-    private final static String PROP_TESTONRETURN = "testOnReturn";\r
-    private final static String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";\r
-    private final static String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";\r
-    private final static String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";\r
-    private final static String PROP_TESTWHILEIDLE = "testWhileIdle";\r
-    private final static String PROP_PASSWORD = "password";\r
-    private final static String PROP_URL = "url";\r
-    private final static String PROP_USERNAME = "username";\r
-    private final static String PROP_VALIDATIONQUERY = "validationQuery";\r
-    private final static String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";\r
-    private final static String PROP_REMOVEABANDONED = "removeAbandoned";\r
-    private final static String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";\r
-    private final static String PROP_LOGABANDONED = "logAbandoned";\r
-    private final static String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";\r
-    private final static String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";\r
-    private final static String PROP_CONNECTIONPROPERTIES = "connectionProperties";\r
-\r
-    private final static String[] ALL_PROPERTIES = {\r
-        PROP_DEFAULTAUTOCOMMIT,\r
-        PROP_DEFAULTREADONLY,\r
-        PROP_DEFAULTTRANSACTIONISOLATION,\r
-        PROP_DEFAULTCATALOG,\r
-        PROP_DRIVERCLASSNAME,\r
-        PROP_MAXACTIVE,\r
-        PROP_MAXIDLE,\r
-        PROP_MINIDLE,\r
-        PROP_INITIALSIZE,\r
-        PROP_MAXWAIT,\r
-        PROP_TESTONBORROW,\r
-        PROP_TESTONRETURN,\r
-        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,\r
-        PROP_NUMTESTSPEREVICTIONRUN,\r
-        PROP_MINEVICTABLEIDLETIMEMILLIS,\r
-        PROP_TESTWHILEIDLE,\r
-        PROP_PASSWORD,\r
-        PROP_URL,\r
-        PROP_USERNAME,\r
-        PROP_VALIDATIONQUERY,\r
-        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,\r
-        PROP_REMOVEABANDONED,\r
-        PROP_REMOVEABANDONEDTIMEOUT,\r
-        PROP_LOGABANDONED,\r
-        PROP_CONNECTIONPROPERTIES\r
-    };\r
-\r
-\r
-\r
-}\r
diff --git a/test/org/apache/tomcat/jdbc/test/TestGCClose.java b/test/org/apache/tomcat/jdbc/test/TestGCClose.java
deleted file mode 100644 (file)
index 6b75ac0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.test;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class TestGCClose extends DefaultTestCase {\r
-    public TestGCClose(String name) {\r
-        super(name);\r
-    }\r
-    \r
-    public void testGCStop() throws Exception {\r
-        init();\r
-        datasource.getConnection();\r
-        System.out.println("Got a connection, but didn't return it");\r
-        tearDown();\r
-        Thread.sleep(10000);\r
-    }\r
-}\r
diff --git a/test/org/apache/tomcat/jdbc/test/TestTimeout.java b/test/org/apache/tomcat/jdbc/test/TestTimeout.java
deleted file mode 100644 (file)
index 049f2a6..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*\r
- * Licensed to the Apache Software Foundation (ASF) under one or more\r
- * contributor license agreements.  See the NOTICE file distributed with\r
- * this work for additional information regarding copyright ownership.\r
- * The ASF licenses this file to You under the Apache License, Version 2.0\r
- * (the "License"); you may not use this file except in compliance with\r
- * the License.  You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.apache.tomcat.jdbc.test;\r
-\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-\r
-/**\r
- * @author Filip Hanik\r
- * @version 1.0\r
- */\r
-public class TestTimeout extends DefaultTestCase {\r
-    public TestTimeout(String name) {\r
-        super(name);\r
-    }\r
-\r
-    AtomicInteger counter = new AtomicInteger(0);\r
-\r
-    public void testCheckoutTimeout() throws Exception {\r
-        try {\r
-            init();\r
-            this.datasource.getPoolProperties().setTestWhileIdle(true);\r
-            this.datasource.getPoolProperties().setTestOnBorrow(false);\r
-            this.datasource.getPoolProperties().setTestOnReturn(false);\r
-            this.datasource.getPoolProperties().setValidationInterval(30000);\r
-            this.datasource.getPoolProperties().setTimeBetweenEvictionRunsMillis(1000);\r
-            this.datasource.getPoolProperties().setMaxActive(20);\r
-            this.datasource.getPoolProperties().setMaxWait(3000);\r
-            this.datasource.getPoolProperties().setRemoveAbandonedTimeout(5000);\r
-            this.datasource.getPoolProperties().setMinEvictableIdleTimeMillis(5000);\r
-            this.datasource.getPoolProperties().setMinIdle(5);\r
-            this.datasource.getPoolProperties().setLogAbandoned(true);\r
-            System.out.println("About to test connection pool:"+datasource);\r
-            for (int i = 0; i < 21; i++) {\r
-                long now = System.currentTimeMillis();\r
-                this.datasource.getConnection();\r
-                long delta = System.currentTimeMillis()-now;\r
-                System.out.println("Got connection #"+i+" in "+delta+" ms.");\r
-            }\r
-        } catch ( Exception x ) {\r
-            x.printStackTrace();\r
-        }finally {\r
-            Thread.sleep(20000);\r
-            tearDown();\r
-        }\r
-    }\r
-\r
-    public void testRemoveAbandoned() throws Exception {\r
-        try {\r
-            init();\r
-            this.datasource.getPoolProperties().setTestWhileIdle(true);\r
-            this.datasource.getPoolProperties().setTestOnBorrow(false);\r
-            this.datasource.getPoolProperties().setTestOnReturn(false);\r
-            this.datasource.getPoolProperties().setValidationInterval(30000);\r
-            this.datasource.getPoolProperties().setTimeBetweenEvictionRunsMillis(1000);\r
-            this.datasource.getPoolProperties().setMaxActive(20);\r
-            this.datasource.getPoolProperties().setMaxWait(3000);\r
-            this.datasource.getPoolProperties().setRemoveAbandonedTimeout(5000);\r
-            this.datasource.getPoolProperties().setMinEvictableIdleTimeMillis(5000);\r
-            this.datasource.getPoolProperties().setMinIdle(5);\r
-            this.datasource.getPoolProperties().setRemoveAbandoned(true);\r
-            this.datasource.getPoolProperties().setLogAbandoned(true);\r
-            System.out.println("About to test connection pool:"+datasource);\r
-            for (int i = 0; i < threadcount; i++) {\r
-                long now = System.currentTimeMillis();\r
-                this.datasource.getConnection();\r
-                long delta = System.currentTimeMillis()-now;\r
-                System.out.println("Got connection #"+i+" in "+delta+" ms.");\r
-            }\r
-        } catch ( Exception x ) {\r
-            x.printStackTrace();\r
-        }finally {\r
-            Thread.sleep(20000);\r
-            tearDown();\r
-        }\r
-    }\r
-\r
-\r
-}\r