/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.engine.classic.extensions.datasources.mondrian; import org.pentaho.reporting.libraries.base.util.LFUMap; import javax.sql.DataSource; import java.io.PrintWriter; import java.io.Serializable; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import java.util.logging.Logger; /** * Mondrian uses the Identity-Hashkey for creating its cache-key. So we better return the same instance for the same * connection information, or caching will be effectively disabled. * * @author Thomas Morgner. */ public class DriverDataSourceCache { private static class DriverConnectionKey implements Serializable { private String jdbcConnectString; private Properties jdbcProperties; private DriverConnectionKey( final String jdbcConnectString, final Properties jdbcProperties ) { if ( jdbcConnectString == null ) { throw new NullPointerException(); } if ( jdbcProperties == null ) { throw new NullPointerException(); } this.jdbcConnectString = jdbcConnectString; this.jdbcProperties = (Properties) jdbcProperties.clone(); } public boolean equals( final Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } final DriverConnectionKey that = (DriverConnectionKey) o; if ( !jdbcConnectString.equals( that.jdbcConnectString ) ) { return false; } if ( !jdbcProperties.equals( that.jdbcProperties ) ) { return false; } return true; } public int hashCode() { int result = jdbcConnectString.hashCode(); result = 31 * result + jdbcProperties.hashCode(); return result; } } /** * Implementation of {@link DataSource} which calls the good ol' {@link java.sql.DriverManager}. */ private static class DriverManagerDataSource implements DataSource { private String jdbcConnectString; private PrintWriter logWriter; private int loginTimeout; private Properties jdbcProperties; public DriverManagerDataSource( final String jdbcConnectString, final Properties properties ) { if ( jdbcConnectString == null ) { throw new NullPointerException(); } if ( properties == null ) { throw new NullPointerException(); } this.jdbcConnectString = jdbcConnectString; this.jdbcProperties = (Properties) properties.clone(); } public Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new SQLFeatureNotSupportedException(); } public boolean equals( final Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } final DriverManagerDataSource that = (DriverManagerDataSource) o; if ( loginTimeout != that.loginTimeout ) { return false; } if ( !jdbcConnectString.equals( that.jdbcConnectString ) ) { return false; } if ( !jdbcProperties.equals( that.jdbcProperties ) ) { return false; } if ( logWriter != null ? !logWriter.equals( that.logWriter ) : that.logWriter != null ) { return false; } return true; } public int hashCode() { int result = jdbcConnectString.hashCode(); result = 31 * result + ( logWriter != null ? logWriter.hashCode() : 0 ); result = 31 * result + loginTimeout; result = 31 * result + jdbcProperties.hashCode(); return result; } public Connection getConnection() throws SQLException { return DriverManager.getConnection( jdbcConnectString, jdbcProperties ); } public Connection getConnection( final String username, final String password ) throws SQLException { final Properties temp = (Properties) jdbcProperties.clone(); if ( username != null ) { temp.put( "user", username ); } if ( password != null ) { temp.put( "password", password ); } return java.sql.DriverManager.getConnection( jdbcConnectString, temp ); } public PrintWriter getLogWriter() throws SQLException { return logWriter; } public void setLogWriter( final PrintWriter out ) throws SQLException { logWriter = out; } public void setLoginTimeout( final int seconds ) throws SQLException { loginTimeout = seconds; } public int getLoginTimeout() throws SQLException { return loginTimeout; } public boolean isWrapperFor( Class c ) { return false; } public <T> T unwrap( Class<T> c ) throws SQLException { throw new SQLException( "This class cannot be unwrapped." ); } } private static LFUMap cache; private DriverDataSourceCache() { } public static synchronized DataSource createDataSource( final String jdbcUrl, final Properties properties ) { if ( cache == null ) { cache = new LFUMap( 20 ); } final DriverConnectionKey key = new DriverConnectionKey( jdbcUrl, properties ); final Object o = cache.get( key ); if ( o instanceof DataSource ) { return (DataSource) o; } final DriverManagerDataSource managerDataSource = new DriverManagerDataSource( jdbcUrl, properties ); cache.put( key, managerDataSource ); return managerDataSource; } }