001/* 002 * Copyright 2002-2016 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.UsesJava7; 024import org.springframework.util.Assert; 025 026/** 027 * Abstract base class for JDBC {@link javax.sql.DataSource} implementations 028 * that operate on a JDBC {@link java.sql.Driver}. 029 * 030 * @author Juergen Hoeller 031 * @since 2.5.5 032 * @see SimpleDriverDataSource 033 * @see DriverManagerDataSource 034 */ 035public abstract class AbstractDriverBasedDataSource extends AbstractDataSource { 036 037 private String url; 038 039 private String username; 040 041 private String password; 042 043 private String catalog; 044 045 private String schema; 046 047 private Properties connectionProperties; 048 049 050 /** 051 * Set the JDBC URL to use for connecting through the Driver. 052 * @see java.sql.Driver#connect(String, java.util.Properties) 053 */ 054 public void setUrl(String url) { 055 Assert.hasText(url, "Property 'url' must not be empty"); 056 this.url = url.trim(); 057 } 058 059 /** 060 * Return the JDBC URL to use for connecting through the Driver. 061 */ 062 public String getUrl() { 063 return this.url; 064 } 065 066 /** 067 * Set the JDBC username to use for connecting through the Driver. 068 * @see java.sql.Driver#connect(String, java.util.Properties) 069 */ 070 public void setUsername(String username) { 071 this.username = username; 072 } 073 074 /** 075 * Return the JDBC username to use for connecting through the Driver. 076 */ 077 public String getUsername() { 078 return this.username; 079 } 080 081 /** 082 * Set the JDBC password to use for connecting through the Driver. 083 * @see java.sql.Driver#connect(String, java.util.Properties) 084 */ 085 public void setPassword(String password) { 086 this.password = password; 087 } 088 089 /** 090 * Return the JDBC password to use for connecting through the Driver. 091 */ 092 public String getPassword() { 093 return this.password; 094 } 095 096 /** 097 * Specify a database catalog to be applied to each Connection. 098 * @since 4.3.2 099 * @see Connection#setCatalog 100 */ 101 public void setCatalog(String catalog) { 102 this.catalog = catalog; 103 } 104 105 /** 106 * Return the database catalog to be applied to each Connection, if any. 107 * @since 4.3.2 108 */ 109 public String getCatalog() { 110 return this.catalog; 111 } 112 113 /** 114 * Specify a database schema to be applied to each Connection. 115 * @since 4.3.2 116 * @see Connection#setSchema 117 */ 118 public void setSchema(String schema) { 119 this.schema = schema; 120 } 121 122 /** 123 * Return the database schema to be applied to each Connection, if any. 124 * @since 4.3.2 125 */ 126 public String getSchema() { 127 return this.schema; 128 } 129 130 /** 131 * Specify arbitrary connection properties as key/value pairs, 132 * to be passed to the Driver. 133 * <p>Can also contain "user" and "password" properties. However, 134 * any "username" and "password" bean properties specified on this 135 * DataSource will override the corresponding connection properties. 136 * @see java.sql.Driver#connect(String, java.util.Properties) 137 */ 138 public void setConnectionProperties(Properties connectionProperties) { 139 this.connectionProperties = connectionProperties; 140 } 141 142 /** 143 * Return the connection properties to be passed to the Driver, if any. 144 */ 145 public Properties getConnectionProperties() { 146 return this.connectionProperties; 147 } 148 149 150 /** 151 * This implementation delegates to {@code getConnectionFromDriver}, 152 * using the default username and password of this DataSource. 153 * @see #getConnectionFromDriver(String, String) 154 * @see #setUsername 155 * @see #setPassword 156 */ 157 @Override 158 public Connection getConnection() throws SQLException { 159 return getConnectionFromDriver(getUsername(), getPassword()); 160 } 161 162 /** 163 * This implementation delegates to {@code getConnectionFromDriver}, 164 * using the given username and password. 165 * @see #getConnectionFromDriver(String, String) 166 */ 167 @Override 168 public Connection getConnection(String username, String password) throws SQLException { 169 return getConnectionFromDriver(username, password); 170 } 171 172 173 /** 174 * Build properties for the Driver, including the given username and password (if any), 175 * and obtain a corresponding Connection. 176 * @param username the name of the user 177 * @param password the password to use 178 * @return the obtained Connection 179 * @throws SQLException in case of failure 180 * @see java.sql.Driver#connect(String, java.util.Properties) 181 */ 182 @UsesJava7 183 protected Connection getConnectionFromDriver(String username, String password) throws SQLException { 184 Properties mergedProps = new Properties(); 185 Properties connProps = getConnectionProperties(); 186 if (connProps != null) { 187 mergedProps.putAll(connProps); 188 } 189 if (username != null) { 190 mergedProps.setProperty("user", username); 191 } 192 if (password != null) { 193 mergedProps.setProperty("password", password); 194 } 195 196 Connection con = getConnectionFromDriver(mergedProps); 197 if (this.catalog != null) { 198 con.setCatalog(this.catalog); 199 } 200 if (this.schema != null) { 201 con.setSchema(this.schema); 202 } 203 return con; 204 } 205 206 /** 207 * Obtain a Connection using the given properties. 208 * <p>Template method to be implemented by subclasses. 209 * @param props the merged connection properties 210 * @return the obtained Connection 211 * @throws SQLException in case of failure 212 */ 213 protected abstract Connection getConnectionFromDriver(Properties props) throws SQLException; 214 215}