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.sql.Connection; 022import java.sql.DatabaseMetaData; 023import java.sql.SQLException; 024import java.util.AbstractMap; 025import java.util.Map; 026import java.util.TreeMap; 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; 033import net.sf.hajdbc.util.ref.ReferenceMap; 034import net.sf.hajdbc.util.ref.SoftReferenceFactory; 035 036/** 037 * Per-database {@link DatabaseMetaDataCache} implementation that populates itself lazily. 038 * @author Paul Ferraro 039 */ 040public class LazyDatabaseMetaDataCache<Z, D extends Database<Z>> implements DatabaseMetaDataCache<Z, D> 041{ 042 private final Map<D, Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>> map = new ReferenceMap<D, Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>>(new TreeMap<D, Reference<Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider>>>(), SoftReferenceFactory.getInstance()); 043 private final DatabaseCluster<Z, D> cluster; 044 045 public LazyDatabaseMetaDataCache(DatabaseCluster<Z, D> cluster) 046 { 047 this.cluster = cluster; 048 } 049 050 /** 051 * {@inheritDoc} 052 * @see net.sf.hajdbc.cache.DatabaseMetaDataCache#flush() 053 */ 054 @Override 055 public void flush() 056 { 057 synchronized (this.map) 058 { 059 this.map.clear(); 060 } 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 synchronized (this.map) 071 { 072 Map.Entry<DatabaseProperties, LazyDatabaseMetaDataProvider> entry = this.map.get(database); 073 074 if (entry == null) 075 { 076 DatabaseMetaData metaData = connection.getMetaData(); 077 Dialect dialect = this.cluster.getDialect(); 078 LazyDatabaseMetaDataProvider provider = new LazyDatabaseMetaDataProvider(metaData); 079 DatabaseProperties properties = new LazyDatabaseProperties(provider, dialect); 080 081 entry = new AbstractMap.SimpleImmutableEntry<DatabaseProperties, LazyDatabaseMetaDataProvider>(properties, provider); 082 083 this.map.put(database, entry); 084 } 085 else 086 { 087 entry.getValue().setConnection(connection); 088 } 089 090 return entry.getKey(); 091 } 092 } 093}