    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    /**
    056     * Sets the transaction registry from the XAConnectionFactory used to create the pool. The transaction registry can
    057     * only be set once using either a connector or this setter method.
    058     *
    059     * @param transactionRegistry
    060     *            the transaction registry acquired from the XAConnectionFactory used to create the pool
    061     */
    062    public void setTransactionRegistry(final TransactionRegistry transactionRegistry) {
    063        if (this.transactionRegistry != null) {
    064            throw new IllegalStateException("TransactionRegistry already set");
    065        }
    066        Objects.requireNonNull(transactionRegistry, "transactionRegistry is null");
    067
    068        this.transactionRegistry = transactionRegistry;
    069    }
    070
    071    @Override
    072    public Connection getConnection() throws SQLException {
    073        if (getPool() == null) {
    074            throw new IllegalStateException("Pool has not been set");
    075        }
    076        if (transactionRegistry == null) {
    077            throw new IllegalStateException("TransactionRegistry has not been set");
    078        }
    079
    080        return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
    081    }
    082}