001package org.javasimon.jdbcx4; 002 003import java.sql.Connection; 004import java.sql.SQLException; 005import java.sql.SQLFeatureNotSupportedException; 006import java.util.logging.Logger; 007import javax.sql.DataSource; 008 009import org.javasimon.jdbc4.SimonConnection; 010import org.javasimon.jdbc4.WrapperSupport; 011 012/** 013 * Wrapper class for real DataSource implementation, produces standard {@link java.sql.Connection} 014 * object. 015 * <p/> 016 * To use SimonDataSource, <b>MUST</b> properties are: 017 * <ul> 018 * <li><code>realDataSourceClassName</code> - full qualified classname of real Datasource 019 * implementation</li> 020 * <li><code>url</code> - JDBC connection URL (no special Simon added tags are needed)</li> 021 * <li><code>user</code> - DB user name</li> 022 * <li><code>password</code> - DB user name</li> 023 * </ul> 024 * <b>MAY</b> properties are: 025 * <ul> 026 * <li><code>prefix</code> - Simon prefix (default: <code>org.javasimon.jdbcx4</code></li> 027 * </ul> 028 * <p/> 029 * As mentioned in package description all <code>getConnection</code> methods 030 * just invokes real {@link javax.sql.DataSource} object methods and wraps obtained 031 * {@link java.sql.Connection} with {@link org.javasimon.jdbc4.SimonConnection} object. 032 * <p/> 033 * Real {@link javax.sql.DataSource} is obtained in method {@link #datasource()}. It tries 034 * to instantiate real datasource object by property <code>realDataSourceClassName</code> 035 * (setters and getters for properties are in {@link AbstractSimonDataSource}) and then sets 036 * basic properties (<code>url</code>, <code>user</code>, <code>password</code>). 037 * 038 * @author Radovan Sninsky 039 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a> 040 * @since 2.4 041 */ 042public final class SimonDataSource extends AbstractSimonDataSource implements DataSource { 043 private DataSource ds; 044 private WrapperSupport<DataSource> wrapperSupport; 045 046 DataSource datasource() throws SQLException { 047 if (ds == null) { 048 ds = createDataSource(DataSource.class); 049 ds.setLogWriter(logWriter); 050 wrapperSupport = new WrapperSupport<>(ds, DataSource.class); 051 } 052 return ds; 053 } 054 055 /** 056 * Attempts to establish a connection with the data source that this {@code DataSource} object represents. 057 * 058 * @return a connection to the data source 059 * @throws java.sql.SQLException if a database access error occurs 060 */ 061 @Override 062 public Connection getConnection() throws SQLException { 063 return new SimonConnection(datasource().getConnection(), getPrefix()); 064 } 065 066 /** 067 * Attempts to establish a connection with the data source that this {@code DataSource} object represents. 068 * 069 * @param user the database user on whose behalf the connection is being made 070 * @param password the user's password 071 * @return a connection to the data source 072 * @throws java.sql.SQLException if a database access error occurs 073 */ 074 @Override 075 public Connection getConnection(String user, String password) throws SQLException { 076 return new SimonConnection(datasource().getConnection(user, password), getPrefix()); 077 } 078 079 @Override 080 public <T> T unwrap(Class<T> iface) throws SQLException { 081 return wrapperSupport.unwrap(iface); 082 } 083 084 @Override 085 public boolean isWrapperFor(Class<?> iface) throws SQLException { 086 return wrapperSupport.isWrapperFor(iface); 087 } 088 089 @Override 090 protected String doGetRealDataSourceClassName() { 091 return this.configuration.getRealDataSourceName(); 092 } 093 094 @Override 095 public Logger getParentLogger() throws SQLFeatureNotSupportedException { 096 return ds.getParentLogger(); 097 } 098}