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
018package org.apache.commons.dbcp2;
019
020import java.sql.Connection;
021import java.sql.DriverManager;
022import java.sql.SQLException;
023import java.util.Properties;
024
025/**
026 * A {@link DriverManager}-based implementation of {@link ConnectionFactory}.
027 *
028 * @since 2.0
029 */
030public class DriverManagerConnectionFactory implements ConnectionFactory {
031
032    static {
033        // Related to DBCP-212
034        // Driver manager does not sync loading of drivers that use the service
035        // provider interface. This will cause issues is multi-threaded
036        // environments. This hack makes sure the drivers are loaded before
037        // DBCP tries to use them.
038        DriverManager.getDrivers();
039    }
040
041    private final String connectionUri;
042
043    private final String userName;
044
045    private final char[] userPassword;
046
047    private final Properties properties;
048
049    /**
050     * Constructor for DriverManagerConnectionFactory.
051     *
052     * @param connectionUri
053     *            a database url of the form <code> jdbc:<em>subprotocol</em>:<em>subname</em></code>
054     * @since 2.2
055     */
056    public DriverManagerConnectionFactory(final String connectionUri) {
057        this.connectionUri = connectionUri;
058        this.properties = new Properties();
059        this.userName = null;
060        this.userPassword = null;
061    }
062
063    /**
064     * Constructor for DriverManagerConnectionFactory.
065     *
066     * @param connectionUri
067     *            a database url of the form <code> jdbc:<em>subprotocol</em>:<em>subname</em></code>
068     * @param properties
069     *            a list of arbitrary string tag/value pairs as connection arguments; normally at least a "user" and
070     *            "password" property should be included.
071     */
072    public DriverManagerConnectionFactory(final String connectionUri, final Properties properties) {
073        this.connectionUri = connectionUri;
074        this.properties = properties;
075        this.userName = null;
076        this.userPassword = null;
077    }
078
079    /**
080     * Constructor for DriverManagerConnectionFactory.
081     *
082     * @param connectionUri
083     *            a database url of the form <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
084     * @param userName
085     *            the database user
086     * @param userPassword
087     *            the user's password
088     */
089    public DriverManagerConnectionFactory(final String connectionUri, final String userName,
090            final char[] userPassword) {
091        this.connectionUri = connectionUri;
092        this.userName = userName;
093        this.userPassword = Utils.clone(userPassword);
094        this.properties = null;
095    }
096
097    /**
098     * Constructor for DriverManagerConnectionFactory.
099     *
100     * @param connectionUri
101     *            a database url of the form <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
102     * @param userName
103     *            the database user
104     * @param userPassword
105     *            the user's password
106     */
107    public DriverManagerConnectionFactory(final String connectionUri, final String userName,
108            final String userPassword) {
109        this.connectionUri = connectionUri;
110        this.userName = userName;
111        this.userPassword =  Utils.toCharArray(userPassword);
112        this.properties = null;
113    }
114
115    @Override
116    public Connection createConnection() throws SQLException {
117        if (null == properties) {
118            if (userName == null && userPassword == null) {
119                return DriverManager.getConnection(connectionUri);
120            }
121            return DriverManager.getConnection(connectionUri, userName, Utils.toString(userPassword));
122        }
123        return DriverManager.getConnection(connectionUri, properties);
124    }
125
126    /**
127     * @return The connection URI.
128     * @since 2.6.0
129     */
130    public String getConnectionUri() {
131        return connectionUri;
132    }
133
134    /**
135     * @return The Properties.
136     * @since 2.6.0
137     */
138    public Properties getProperties() {
139        return properties;
140    }
141
142    /**
143     * @return The user name.
144     * @since 2.6.0
145     */
146    public String getUserName() {
147        return userName;
148    }
149}