    001/**
    002 *
    003 * Licensed to the Apache Software Foundation (ASF) under one or more
    004 * contributor license agreements.  See the NOTICE file distributed with
    005 * this work for additional information regarding copyright ownership.
    006 * The ASF licenses this file to You under the Apache License, Version 2.0
    007 * (the "License"); you may not use this file except in compliance with
    008 * the License.  You may obtain a copy of the License at
    009 *
    010 *     http://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 *  Unless required by applicable law or agreed to in writing, software
    013 *  distributed under the License is distributed on an "AS IS" BASIS,
    014 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    015 *  See the License for the specific language governing permissions and
    016 *  limitations under the License.
    017 */
    018package org.apache.commons.dbcp2.managed;
    019
    020import org.apache.commons.pool2.ObjectPool;
    021import org.apache.commons.dbcp2.PoolingDataSource;
    022
    023import java.sql.Connection;
    024import java.sql.SQLException;
    025import java.util.Objects;
    026
    027/**
    028 * The ManagedDataSource is a PoolingDataSource that creates ManagedConnections.
    029 *
    030 * @param <C>
    031 *            The kind of {@link Connection} to manage.
    032 * @since 2.0
    033 */
    034public class ManagedDataSource<C extends Connection> extends PoolingDataSource<C> {
    035    private TransactionRegistry transactionRegistry;
    036
    037    /**
    038     * Creates a ManagedDataSource which obtains connections from the specified pool and manages them using the
    039     * specified transaction registry. The TransactionRegistry must be the transaction registry obtained from the
    040     * XAConnectionFactory used to create the connection pool. If not, an error will occur when attempting to use the
    041     * connection in a global transaction because the XAResource object associated with the connection will be
    042     * unavailable.
    043     *
    044     * @param pool
    045     *            the connection pool
    046     * @param transactionRegistry
    047     *            the transaction registry obtained from the XAConnectionFactory used to create the connection pool
    048     *            object factory
    049     */
    050    public ManagedDataSource(final ObjectPool<C> pool, final TransactionRegistry transactionRegistry) {
    051        super(pool);
    052        this.transactionRegistry = transactionRegistry;
    053    }
    054
    055    @Override
    056    public Connection getConnection() throws SQLException {
    057        if (getPool() == null) {
    058            throw new IllegalStateException("Pool has not been set");
    059        }
    060        if (transactionRegistry == null) {
    061            throw new IllegalStateException("TransactionRegistry has not been set");
    062        }
    063
    064        return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
    065    }
    066
    067    /**
    068     * Gets the transaction registry.
    069     *
    070     * @return The transaction registry.
    071     * @see #setTransactionRegistry(TransactionRegistry)
    072     * @since 2.6.0
    073     */
    074    public TransactionRegistry getTransactionRegistry() {
    075        return transactionRegistry;
    076    }
    077
    078    /**
    079     * Sets the transaction registry from the XAConnectionFactory used to create the pool. The transaction registry can
    080     * only be set once using either a connector or this setter method.
    081     *
    082     * @param transactionRegistry
    083     *            the transaction registry acquired from the XAConnectionFactory used to create the pool
    084     */
    085    public void setTransactionRegistry(final TransactionRegistry transactionRegistry) {
    086        if (this.transactionRegistry != null) {
    087            throw new IllegalStateException("TransactionRegistry already set");
    088        }
    089        Objects.requireNonNull(transactionRegistry, "transactionRegistry is null");
    090
    091        this.transactionRegistry = transactionRegistry;
    092    }
    093}