001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.dbcp.managed;
019    import java.sql.Connection;
020    import java.util.Collection;
021    
022    import org.apache.commons.dbcp.AbandonedConfig;
023    import org.apache.commons.dbcp.PoolableConnectionFactory;
024    import org.apache.commons.dbcp.PoolingConnection;
025    import org.apache.commons.pool.KeyedObjectPool;
026    import org.apache.commons.pool.KeyedObjectPoolFactory;
027    import org.apache.commons.pool.ObjectPool;
028    
029    /**
030     * A {@link PoolableConnectionFactory} that creates {@link PoolableManagedConnection}s.
031     * 
032     * @version $Revision: 892307 $ $Date: 2013-12-31 23:27:28 +0000 (Tue, 31 Dec 2013) $
033     */
034    public class PoolableManagedConnectionFactory extends PoolableConnectionFactory {
035    
036        /** Transaction registry associated with connections created by this factory */
037        private final TransactionRegistry transactionRegistry;
038        
039        /**
040         * Create a PoolableManagedConnectionFactory and attach it to a connection pool.
041         * 
042         * @param connFactory XAConnectionFactory
043         * @param pool connection pool 
044         * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling
045         * {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
046         * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.
047         * Should return at least one row. Using <tt>null</tt> turns off validation.
048         * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
049         * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
050         */
051        public PoolableManagedConnectionFactory(XAConnectionFactory connFactory,
052                ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory,
053                String validationQuery, boolean defaultReadOnly,
054                boolean defaultAutoCommit) {
055            super(connFactory, pool, stmtPoolFactory, validationQuery,
056                    defaultReadOnly, defaultAutoCommit);
057            this.transactionRegistry = connFactory.getTransactionRegistry();
058        }
059        
060        /**
061         * Create a PoolableManagedConnectionFactory and attach it to a connection pool.
062         * 
063         * @param connFactory XAConnectionFactory
064         * @param pool connection pool 
065         * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling
066         * {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
067         * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.
068         * Should return at least one row. Using <tt>null</tt> turns off validation.
069         * @param validationQueryTimeout the number of seconds that validation queries will wait for database response
070         * before failing. Use a value less than or equal to 0 for no timeout.
071         * @param connectionInitSqls a Collection of SQL statements to initialize {@link Connection}s.
072         * Using <tt>null</tt> turns off initialization.
073         * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
074         * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
075         * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
076         * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
077         * @param config the AbandonedConfig if tracing SQL objects
078         */
079        public PoolableManagedConnectionFactory(XAConnectionFactory connFactory,
080                ObjectPool pool,
081                KeyedObjectPoolFactory stmtPoolFactory,
082                String validationQuery,
083                int validationQueryTimeout,
084                Collection connectionInitSqls,
085                Boolean defaultReadOnly,
086                boolean defaultAutoCommit,
087                int defaultTransactionIsolation,
088                String defaultCatalog,
089                AbandonedConfig config) {
090            super(connFactory, pool, stmtPoolFactory, validationQuery, validationQueryTimeout, connectionInitSqls,
091                    defaultReadOnly, defaultAutoCommit, defaultTransactionIsolation, defaultCatalog, config);
092            this.transactionRegistry = connFactory.getTransactionRegistry();
093        }
094    
095        /**
096         * Uses the configured XAConnectionFactory to create a {@link PoolableManagedConnection}.
097         * Throws <code>IllegalStateException</code> if the connection factory returns null.
098         * Also initializes the connection using configured initialization sql (if provided)
099         * and sets up a prepared statement pool associated with the PoolableManagedConnection
100         * if statement pooling is enabled.
101         */
102        synchronized public Object makeObject() throws Exception {
103            Connection conn = _connFactory.createConnection();
104            if (conn == null) {
105                throw new IllegalStateException("Connection factory returned null from createConnection");
106            }
107            initializeConnection(conn);
108            if(null != _stmtPoolFactory) {
109                KeyedObjectPool stmtpool = _stmtPoolFactory.createPool();
110                conn = new PoolingConnection(conn,stmtpool);
111                stmtpool.setFactory((PoolingConnection)conn);
112            }
113            return new PoolableManagedConnection(transactionRegistry,conn,_pool,_config);
114        }
115    
116    }