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     */
018    package org.apache.commons.dbcp.managed;
019    
020    import javax.sql.XAConnection;
021    import javax.sql.XADataSource;
022    import javax.transaction.TransactionManager;
023    import javax.transaction.xa.XAResource;
024    import java.sql.Connection;
025    import java.sql.SQLException;
026    
027    /**
028     * An implementation of XAConnectionFactory which uses a real XADataSource to obtain connections and XAResources.
029     *
030     * @author Dain Sundstrom
031     * @version $Revision: 892307 $
032     */
033    public class DataSourceXAConnectionFactory implements XAConnectionFactory {
034        protected TransactionRegistry transactionRegistry;
035        protected XADataSource xaDataSource;
036        protected String username;
037        protected String password;
038    
039        /**
040         * Creates an DataSourceXAConnectionFactory which uses the specified XADataSource to create database
041         * connections.  The connections are enlisted into transactions using the specified transaction manager.
042         *
043         * @param transactionManager the transaction manager in which connections will be enlisted
044         * @param xaDataSource the data source from which connections will be retrieved
045         */
046        public DataSourceXAConnectionFactory(TransactionManager transactionManager, XADataSource xaDataSource) {
047            this(transactionManager, xaDataSource, null, null);
048        }
049    
050        /**
051         * Creates an DataSourceXAConnectionFactory which uses the specified XADataSource to create database
052         * connections.  The connections are enlisted into transactions using the specified transaction manager.
053         *
054         * @param transactionManager the transaction manager in which connections will be enlisted
055         * @param xaDataSource the data source from which connections will be retrieved
056         * @param username the username used for authenticating new connections or null for unauthenticated
057         * @param password the password used for authenticating new connections
058         */
059        public DataSourceXAConnectionFactory(TransactionManager transactionManager, XADataSource xaDataSource, String username, String password) {
060            if (transactionManager == null) throw new NullPointerException("transactionManager is null");
061            if (xaDataSource == null) throw new NullPointerException("xaDataSource is null");
062    
063            this.transactionRegistry = new TransactionRegistry(transactionManager);
064            this.xaDataSource = xaDataSource;
065            this.username = username;
066            this.password = password;
067        }
068    
069        /**
070         * Gets the username used to authenticate new connections.
071         * @return the user name or null if unauthenticated connections are used
072         */
073        public String getUsername() {
074            return username;
075        }
076    
077        /**
078         * Sets the username used to authenticate new connections.
079         * @param username the username used for authenticating the connection or null for unauthenticated
080         */
081        public void setUsername(String username) {
082            this.username = username;
083        }
084    
085        /**
086         * Sets the password used to authenticate new connections.
087         * @param password the password used for authenticating the connection or null for unauthenticated
088         */
089        public void setPassword(String password) {
090            this.password = password;
091        }
092    
093        public TransactionRegistry getTransactionRegistry() {
094            return transactionRegistry;
095        }
096    
097        public Connection createConnection() throws SQLException {
098            // create a new XAConection
099            XAConnection xaConnection;
100            if (username == null) {
101                xaConnection = xaDataSource.getXAConnection();
102            } else {
103                xaConnection = xaDataSource.getXAConnection(username, password);
104            }
105    
106            // get the real connection and XAResource from the connection
107            Connection connection = xaConnection.getConnection();
108            XAResource xaResource = xaConnection.getXAResource();
109    
110            // register the xa resource for the connection
111            transactionRegistry.registerConnection(connection, xaResource);
112    
113            return connection;
114        }
115    }