4 package eu
.etaxonomy
.cdm
.database
;
6 import java
.io
.PrintWriter
;
7 import java
.net
.URISyntaxException
;
8 import java
.sql
.Connection
;
9 import java
.sql
.DatabaseMetaData
;
10 import java
.sql
.PreparedStatement
;
11 import java
.sql
.ResultSet
;
12 import java
.sql
.SQLException
;
13 import java
.sql
.SQLFeatureNotSupportedException
;
16 import javax
.sql
.DataSource
;
18 import org
.apache
.log4j
.Logger
;
19 import org
.hibernate
.cache
.spi
.RegionFactory
;
20 import org
.springframework
.beans
.factory
.config
.BeanDefinition
;
22 import com
.mchange
.v2
.c3p0
.ComboPooledDataSource
;
24 import eu
.etaxonomy
.cdm
.config
.CdmSourceException
;
25 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaDataPropertyName
;
26 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.HibernateConfiguration
;
29 * This class is a wrapper class to wrap an {@link javax.sql.DataSource} to an
30 * {@link ICdmDataSource}. As the former is a very limited interface it is not possible
31 * to implement all methods of {@link ICdmDataSource}. However, the aim is
32 * to implement all those methods which are usually needed to work with a datasource
33 * which represents a connection to a database such as transaction handling and
35 * Those methods which are not supported by this wrapper class will throw an xxx
42 //FIXME this class replicates lots of code in CdmDataSourceBase, we may want to merge it
43 //in a common helper class to avoid redundant code
44 public class WrappedCdmDataSource
implements ICdmDataSource
{
45 private static final Logger logger
= Logger
.getLogger(WrappedCdmDataSource
.class);
48 private final DataSource datasource
;
50 private Connection connection
;
53 public WrappedCdmDataSource(DataSource datasource
) {
54 if (datasource
== null){
55 throw new NullPointerException("datasource must not be null for WrappedCdmDataSource");
57 this.datasource
= datasource
;
64 public Connection
getConnection() throws SQLException
{
65 if (this.connection
== null){
66 this.connection
= datasource
.getConnection();
68 return this.connection
;
72 public Connection
getConnection(String username
, String password
) throws SQLException
{
73 if (this.connection
== null){
74 this.connection
= datasource
.getConnection(username
, password
);
80 public PrintWriter
getLogWriter() throws SQLException
{
81 return datasource
.getLogWriter();
85 public void setLogWriter(PrintWriter out
) throws SQLException
{
86 datasource
.setLogWriter(out
);
90 public void setLoginTimeout(int seconds
) throws SQLException
{
91 datasource
.setLoginTimeout(seconds
);
95 public int getLoginTimeout() throws SQLException
{
96 return datasource
.getLoginTimeout();
100 public java
.util
.logging
.Logger
getParentLogger() throws SQLFeatureNotSupportedException
{
101 return datasource
.getParentLogger();
105 public <T
> T
unwrap(Class
<T
> iface
) throws SQLException
{
106 return datasource
.unwrap(iface
);
110 public boolean isWrapperFor(Class
<?
> iface
) throws SQLException
{
111 return datasource
.isWrapperFor(iface
);
115 public String
getName() {
116 throw new UnsupportedOperationException("getName() not supported by WrappedCdmDataSource");
120 public void setName(String name
) {
121 throw new UnsupportedOperationException("setName(String) not supported by WrappedCdmDataSource");
125 public String
getServer() {
126 //TODO we may want to use client info from connection here
127 throw new UnsupportedOperationException("getServer() not supported by WrappedCdmDataSource");
131 public void setServer(String server
) {
132 throw new UnsupportedOperationException("setServer() not supported by WrappedCdmDataSource");
136 public int getPort() {
137 //TODO we may want to use client info from connection here
138 throw new UnsupportedOperationException("getPort() not supported by WrappedCdmDataSource");
142 public void setPort(int port
) {
143 throw new UnsupportedOperationException("setPort(int) not supported by WrappedCdmDataSource");
147 public String
getDbSchemaVersion() throws CdmSourceException
{
149 return (String
)getSingleValue(CdmMetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQuery());
150 } catch (SQLException e1
) {
152 return (String
)getSingleValue(CdmMetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQueryOld());
153 } catch (SQLException e
) {
154 throw new CdmSourceException(e
.getMessage());
161 public boolean isDbEmpty() throws CdmSourceException
{
162 // Any CDM DB should have a schema version
163 String dbSchemaVersion
= getDbSchemaVersion();
164 return (dbSchemaVersion
== null || dbSchemaVersion
.equals(""));
168 public boolean checkConnection() throws CdmSourceException
{
170 return testConnection();
171 } catch (ClassNotFoundException e
) {
172 throw new CdmSourceException(e
.getMessage());
173 } catch (SQLException e
) {
174 throw new CdmSourceException(e
.getMessage());
179 public String
getConnectionMessage() {
181 Connection connection
= getConnection();
182 String message
= "Connecting to datasource " + connection
.getSchema() + ".";
184 } catch (SQLException e
) {
185 throw new RuntimeException(e
);
190 public void closeOpenConnections() {
192 if(connection
!= null && !connection
.isClosed()){
196 } catch (SQLException e
) {
197 logger
.error("Error closing the connection");
202 public Map
<CdmMetaDataPropertyName
, String
> getMetaDataMap() throws CdmSourceException
{
203 //TODO is it possible/required to build a meta data map here?
204 throw new UnsupportedOperationException("getMetaDataMap() not supported by WrappedCdmDataSource");
208 public BeanDefinition
getDatasourceBean() {
209 //TODO is it possible/required to build a datasource bean here?
210 throw new UnsupportedOperationException("getDatasourceBean() not supported by WrappedCdmDataSource");
214 public BeanDefinition
getHibernatePropertiesBean(DbSchemaValidation hbm2dll
) {
215 //TODO is it possible/required to build a properties bean here?
216 throw new UnsupportedOperationException("getHibernatePropertiesBean() not supported by WrappedCdmDataSource");
221 public BeanDefinition
getHibernatePropertiesBean(DbSchemaValidation hbm2dll
,
222 Boolean showSql
, Boolean formatSql
, Boolean registerSearchListener
,
223 Class
<?
extends RegionFactory
> cacheProviderClass
) {
224 //TODO is it possible/required to build a properties bean here?
225 throw new UnsupportedOperationException("getHibernatePropertiesBean() not supported by WrappedCdmDataSource");
232 public BeanDefinition
getHibernatePropertiesBean(DbSchemaValidation hbm2dll
,
233 HibernateConfiguration hibernateConfig
) {
234 //TODO is it possible/required to build a properties bean here?
235 throw new UnsupportedOperationException("getHibernatePropertiesBean() not supported by WrappedCdmDataSource");
239 public String
getFilePath() {
240 throw new UnsupportedOperationException("getFilePath() not supported by WrappedCdmDataSource");
244 public H2Mode
getMode() {
245 throw new UnsupportedOperationException("getMode() not supported by WrappedCdmDataSource");
249 public String
getUsername() {
250 //TODO maybe this can be implemented by connection meta data
251 throw new UnsupportedOperationException("getUsername() not supported by WrappedCdmDataSource");
255 public String
getPassword() {
256 throw new UnsupportedOperationException("getPassword() not supported by WrappedCdmDataSource");
260 public String
getDatabase() {
261 if(datasource
instanceof ComboPooledDataSource
) {
262 String jdbcUrl
= ((ComboPooledDataSource
)datasource
).getJdbcUrl();
264 return getDatabaseFrom(jdbcUrl
);
265 } catch (URISyntaxException e
) {
266 throw new RuntimeException(e
);
269 throw new UnsupportedOperationException("getDatabase() not implemented for " + datasource
.getClass() + " in WrappedCdmDataSource");
277 * @throws URISyntaxException
279 private String
getDatabaseFrom(String jdbcUrl
) throws URISyntaxException
{
280 DatabaseTypeEnum type
= DatabaseTypeEnum
.byConnectionString(jdbcUrl
);
284 String dbName
= type
.getDatabaseType().getDatabaseNameByConnectionString(jdbcUrl
);
290 public void setMode(H2Mode h2Mode
) {
291 throw new UnsupportedOperationException("setMode(H2Mode) not supported by WrappedCdmDataSource");
295 public void setUsername(String username
) {
296 throw new UnsupportedOperationException("setUsername(String) not supported by WrappedCdmDataSource");
300 public void setPassword(String password
) {
301 throw new UnsupportedOperationException("setPassword(String) not supported by WrappedCdmDataSource");
305 public void setDatabase(String database
) {
306 throw new UnsupportedOperationException("setDatabase(String) not supported by WrappedCdmDataSource");
310 public DatabaseTypeEnum
getDatabaseType() {
311 if (this.datasource
instanceof ICdmDataSource
){
312 return ((ICdmDataSource
)this.datasource
).getDatabaseType();
317 } catch (SQLException e1
) {
318 throw new RuntimeException("SQL Exception while trying to establish connection to datasource");
321 String driverName
= null;
322 if (connection
!= null){
323 DatabaseMetaData metaData
= null;
325 metaData
= connection
.getMetaData();
326 } catch (SQLException e
) {
327 throw new RuntimeException("SQL Exception while trying to read datasource metadata");
331 driverName
= metaData
!= null ? metaData
.getDriverName() : null;
332 } catch (SQLException e
) {
333 //throw exception at end
335 if (metaData
!= null){
336 DatabaseTypeEnum type
= DatabaseTypeEnum
.byDatabaseMetaData(metaData
);
341 throw new IllegalStateException("datasource type (MySQL, SQL Server, ...) could not be retrieved from generic datasource");
344 throw new IllegalStateException("datasource type (MySQL, SQL Server, ...) could not be retrieved from generic datasource");
348 public boolean testConnection() throws ClassNotFoundException
, SQLException
{
349 return getConnection() != null;
353 public ResultSet
executeQuery(String query
) throws SQLException
{
354 PreparedStatement a
= getConnection().prepareStatement(query
);
355 return a
.executeQuery();
359 public int executeUpdate(String sqlUpdate
) throws SQLException
{
360 PreparedStatement a
= getConnection().prepareStatement(sqlUpdate
);
361 return a
.executeUpdate();
365 public void startTransaction() {
367 Connection connection
= getConnection();
368 this.connection
= connection
;
369 connection
.setAutoCommit(false);
370 } catch (SQLException e
) {
371 throw new RuntimeException(e
);
376 public void commitTransaction() throws SQLException
{
377 getConnection().commit();
381 public void rollback() throws SQLException
{
382 getConnection().rollback();
386 public Object
getSingleValue(String query
) throws SQLException
{
387 ResultSet rs
= this.executeQuery(query
);
389 int count
= rs
.getMetaData().getColumnCount();
391 return rs
.getObject(1);
398 public DatabaseMetaData
getMetaData() {
400 return getConnection().getMetaData();
401 } catch (SQLException e
) {
402 throw new RuntimeException(e
);