001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jdbc.datasource; 018 019import java.sql.Connection; 020import java.sql.SQLException; 021import java.util.Properties; 022 023import org.springframework.lang.Nullable; 024 025/** 026 * Abstract base class for JDBC {@link javax.sql.DataSource} implementations 027 * that operate on a JDBC {@link java.sql.Driver}. 028 * 029 * @author Juergen Hoeller 030 * @since 2.5.5 031 * @see SimpleDriverDataSource 032 * @see DriverManagerDataSource 033 */ 034public abstract class AbstractDriverBasedDataSource extends AbstractDataSource { 035 036 @Nullable 037 private String url; 038 039 @Nullable 040 private String username; 041 042 @Nullable 043 private String password; 044 045 @Nullable 046 private String catalog; 047 048 @Nullable 049 private String schema; 050 051 @Nullable 052 private Properties connectionProperties; 053 054 055 /** 056 * Set the JDBC URL to use for connecting through the Driver. 057 * @see java.sql.Driver#connect(String, java.util.Properties) 058 */ 059 public void setUrl(@Nullable String url) { 060 this.url = (url != null ? url.trim() : null); 061 } 062 063 /** 064 * Return the JDBC URL to use for connecting through the Driver. 065 */ 066 @Nullable 067 public String getUrl() { 068 return this.url; 069 } 070 071 /** 072 * Set the JDBC username to use for connecting through the Driver. 073 * @see java.sql.Driver#connect(String, java.util.Properties) 074 */ 075 public void setUsername(@Nullable String username) { 076 this.username = username; 077 } 078 079 /** 080 * Return the JDBC username to use for connecting through the Driver. 081 */ 082 @Nullable 083 public String getUsername() { 084 return this.username; 085 } 086 087 /** 088 * Set the JDBC password to use for connecting through the Driver. 089 * @see java.sql.Driver#connect(String, java.util.Properties) 090 */ 091 public void setPassword(@Nullable String password) { 092 this.password = password; 093 } 094 095 /** 096 * Return the JDBC password to use for connecting through the Driver. 097 */ 098 @Nullable 099 public String getPassword() { 100 return this.password; 101 } 102 103 /** 104 * Specify a database catalog to be applied to each Connection. 105 * @since 4.3.2 106 * @see Connection#setCatalog 107 */ 108 public void setCatalog(@Nullable String catalog) { 109 this.catalog = catalog; 110 } 111 112 /** 113 * Return the database catalog to be applied to each Connection, if any. 114 * @since 4.3.2 115 */ 116 @Nullable 117 public String getCatalog() { 118 return this.catalog; 119 } 120 121 /** 122 * Specify a database schema to be applied to each Connection. 123 * @since 4.3.2 124 * @see Connection#setSchema 125 */ 126 public void setSchema(@Nullable String schema) { 127 this.schema = schema; 128 } 129 130 /** 131 * Return the database schema to be applied to each Connection, if any. 132 * @since 4.3.2 133 */ 134 @Nullable 135 public String getSchema() { 136 return this.schema; 137 } 138 139 /** 140 * Specify arbitrary connection properties as key/value pairs, 141 * to be passed to the Driver. 142 * <p>Can also contain "user" and "password" properties. However, 143 * any "username" and "password" bean properties specified on this 144 * DataSource will override the corresponding connection properties. 145 * @see java.sql.Driver#connect(String, java.util.Properties) 146 */ 147 public void setConnectionProperties(@Nullable Properties connectionProperties) { 148 this.connectionProperties = connectionProperties; 149 } 150 151 /** 152 * Return the connection properties to be passed to the Driver, if any. 153 */ 154 @Nullable 155 public Properties getConnectionProperties() { 156 return this.connectionProperties; 157 } 158 159 160 /** 161 * This implementation delegates to {@code getConnectionFromDriver}, 162 * using the default username and password of this DataSource. 163 * @see #getConnectionFromDriver(String, String) 164 * @see #setUsername 165 * @see #setPassword 166 */ 167 @Override 168 public Connection getConnection() throws SQLException { 169 return getConnectionFromDriver(getUsername(), getPassword()); 170 } 171 172 /** 173 * This implementation delegates to {@code getConnectionFromDriver}, 174 * using the given username and password. 175 * @see #getConnectionFromDriver(String, String) 176 */ 177 @Override 178 public Connection getConnection(String username, String password) throws SQLException { 179 return getConnectionFromDriver(username, password); 180 } 181 182 183 /** 184 * Build properties for the Driver, including the given username and password (if any), 185 * and obtain a corresponding Connection. 186 * @param username the name of the user 187 * @param password the password to use 188 * @return the obtained Connection 189 * @throws SQLException in case of failure 190 * @see java.sql.Driver#connect(String, java.util.Properties) 191 */ 192 protected Connection getConnectionFromDriver(@Nullable String username, @Nullable String password) throws SQLException { 193 Properties mergedProps = new Properties(); 194 Properties connProps = getConnectionProperties(); 195 if (connProps != null) { 196 mergedProps.putAll(connProps); 197 } 198 if (username != null) { 199 mergedProps.setProperty("user", username); 200 } 201 if (password != null) { 202 mergedProps.setProperty("password", password); 203 } 204 205 Connection con = getConnectionFromDriver(mergedProps); 206 if (this.catalog != null) { 207 con.setCatalog(this.catalog); 208 } 209 if (this.schema != null) { 210 con.setSchema(this.schema); 211 } 212 return con; 213 } 214 215 /** 216 * Obtain a Connection using the given properties. 217 * <p>Template method to be implemented by subclasses. 218 * @param props the merged connection properties 219 * @return the obtained Connection 220 * @throws SQLException in case of failure 221 */ 222 protected abstract Connection getConnectionFromDriver(Properties props) throws SQLException; 223 224}