/*!
* 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 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;
import javax.sql.DataSource;
import org.pentaho.reporting.libraries.base.util.LFUMap;
/**
* 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;
}
}