001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (c) 2004-2007 Paul Ferraro
004 * 
005 * This library is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published by the 
007 * Free Software Foundation; either version 2.1 of the License, or (at your 
008 * option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT
011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
013 * for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this library; if not, write to the Free Software Foundation, 
017 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018 * 
019 * Contact: ferraro@users.sourceforge.net
020 */
021package net.sf.hajdbc.cache;
022
023import java.sql.SQLException;
024import java.util.Collection;
025import java.util.Map;
026
027import net.sf.hajdbc.ColumnProperties;
028import net.sf.hajdbc.ForeignKeyConstraint;
029import net.sf.hajdbc.QualifiedName;
030import net.sf.hajdbc.UniqueConstraint;
031import net.sf.hajdbc.util.ref.VolatileReference;
032
033/**
034 * @author Paul Ferraro
035 *
036 */
037public class LazyTableProperties extends AbstractTableProperties
038{
039        private final DatabaseMetaDataProvider metaDataProvider;
040        private final QualifiedName table;
041        private final DatabaseMetaDataSupport support;
042        
043        private final VolatileReference<Map<String, ColumnProperties>> columnMapRef = new VolatileReference<Map<String, ColumnProperties>>();
044        private final VolatileReference<UniqueConstraint> primaryKeyRef = new VolatileReference<UniqueConstraint>();
045        private final VolatileReference<Collection<UniqueConstraint>> uniqueConstraintsRef = new VolatileReference<Collection<UniqueConstraint>>();
046        private final VolatileReference<Collection<ForeignKeyConstraint>> foreignKeyConstraintsRef = new VolatileReference<Collection<ForeignKeyConstraint>>();
047        private final VolatileReference<Collection<String>> identityColumnsRef = new VolatileReference<Collection<String>>();
048        
049        public LazyTableProperties(DatabaseMetaDataProvider metaDataProvider, DatabaseMetaDataSupport support, QualifiedName table)
050        {
051                super(support, table);
052                
053                this.metaDataProvider = metaDataProvider;
054                this.support = support;
055                this.table = table;
056        }
057
058        protected Map<String, ColumnProperties> getColumnMap() throws SQLException
059        {
060                synchronized (this.columnMapRef)
061                {
062                        Map<String, ColumnProperties> map = this.columnMapRef.get();
063                        
064                        if (map == null)
065                        {
066                                map = this.support.getColumns(this.metaDataProvider.getDatabaseMetaData(), this.table);
067                                
068                                this.columnMapRef.set(map);
069                        }
070                        
071                        return map;
072                }
073        }
074        
075        /**
076         * @see net.sf.hajdbc.TableProperties#getPrimaryKey()
077         */
078        @Override
079        public UniqueConstraint getPrimaryKey() throws SQLException
080        {
081                synchronized (this.primaryKeyRef)
082                {
083                        UniqueConstraint key = this.primaryKeyRef.get();
084                        
085                        if (key == null)
086                        {
087                                key = this.support.getPrimaryKey(this.metaDataProvider.getDatabaseMetaData(), this.table);
088                                
089                                this.primaryKeyRef.set(key);
090                        }
091                        
092                        return key;
093                }
094        }
095
096        /**
097         * @see net.sf.hajdbc.TableProperties#getForeignKeyConstraints()
098         */
099        @Override
100        public Collection<ForeignKeyConstraint> getForeignKeyConstraints() throws SQLException
101        {
102                synchronized (this.foreignKeyConstraintsRef)
103                {
104                        Collection<ForeignKeyConstraint> keys = this.foreignKeyConstraintsRef.get();
105                        
106                        if (keys == null)
107                        {
108                                keys = this.support.getForeignKeyConstraints(this.metaDataProvider.getDatabaseMetaData(), this.table);
109                                
110                                this.foreignKeyConstraintsRef.set(keys);
111                        }
112                        
113                        return keys;
114                }
115        }
116
117        /**
118         * @see net.sf.hajdbc.TableProperties#getUniqueConstraints()
119         */
120        @Override
121        public Collection<UniqueConstraint> getUniqueConstraints() throws SQLException
122        {
123                synchronized (this.uniqueConstraintsRef)
124                {
125                        Collection<UniqueConstraint> keys = this.uniqueConstraintsRef.get();
126                        
127                        if (keys == null)
128                        {
129                                keys = this.support.getUniqueConstraints(this.metaDataProvider.getDatabaseMetaData(), this.table, this.getPrimaryKey());
130                                
131                                this.uniqueConstraintsRef.set(keys);
132                        }
133                        
134                        return keys;
135                }
136        }
137
138        /**
139         * @see net.sf.hajdbc.TableProperties#getIdentityColumns()
140         */
141        @Override
142        public Collection<String> getIdentityColumns() throws SQLException
143        {
144                synchronized (this.identityColumnsRef)
145                {
146                        Collection<String> columns = this.identityColumnsRef.get();
147                        
148                        if (columns == null)
149                        {
150                                columns = this.support.getIdentityColumns(this.getColumnMap().values());
151                                
152                                this.identityColumnsRef.set(columns);
153                        }
154                        
155                        return columns;
156                }
157        }
158}