001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.cache.lazy; 019 020import java.lang.ref.Reference; 021import java.lang.ref.SoftReference; 022import java.sql.Connection; 023import java.sql.DatabaseMetaData; 024import java.sql.SQLException; 025import java.util.AbstractMap; 026import java.util.Map; 027 028import net.sf.hajdbc.Database; 029import net.sf.hajdbc.DatabaseCluster; 030import net.sf.hajdbc.DatabaseProperties; 031import net.sf.hajdbc.cache.DatabaseMetaDataCache; 032import net.sf.hajdbc.dialect.Dialect; 033 034 035/** 036 * DatabaseMetaDataCache implementation that lazily caches data when requested. 037 * Used when a compromise between memory usage and performance is desired. 038 * Caches DatabaseProperties using a soft reference to prevent <code>OutOfMemoryError</code>s. 039 * 040 * @author Paul Ferraro 041 * @since 2.0 042 */ 043public class SharedLazyDatabaseMetaDataCache<Z, D extends Database<Z>> implements DatabaseMetaDataCache<Z, D> 044{ 045 private final DatabaseCluster<Z, D> cluster; 046 047 private volatile Reference<Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>> entryRef = new SoftReference<Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>>(null); 048 049 public SharedLazyDatabaseMetaDataCache(DatabaseCluster<Z, D> cluster) 050 { 051 this.cluster = cluster; 052 } 053 054 /** 055 * @see net.sf.hajdbc.cache.DatabaseMetaDataCache#flush() 056 */ 057 @Override 058 public synchronized void flush() 059 { 060 this.entryRef.clear(); 061 } 062 063 /** 064 * {@inheritDoc} 065 * @see net.sf.hajdbc.cache.DatabaseMetaDataCache#getDatabaseProperties(net.sf.hajdbc.Database, java.sql.Connection) 066 */ 067 @Override 068 public DatabaseProperties getDatabaseProperties(D database, Connection connection) throws SQLException 069 { 070 Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider> entry = this.entryRef.get(); 071 072 if (entry == null) 073 { 074 DatabaseMetaData metaData = connection.getMetaData(); 075 Dialect dialect = this.cluster.getDialect(); 076 LazyDatabaseMetaDataProvider provider = new LazyDatabaseMetaDataProvider(metaData); 077 DatabaseProperties properties = new LazyDatabaseProperties(provider, dialect); 078 079 entry = new AbstractMap.SimpleImmutableEntry<DatabaseProperties, LazyDatabaseMetaDataProvider>(properties, provider); 080 081 this.entryRef = new SoftReference<Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>>(entry); 082 } 083 else 084 { 085 entry.getValue().setConnection(connection); 086 } 087 088 return entry.getKey(); 089 } 090}