001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (c) 2004-2008 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.sql;
022
023import java.lang.reflect.InvocationHandler;
024import java.sql.SQLException;
025import java.util.Hashtable;
026
027import javax.naming.Context;
028import javax.naming.Name;
029import javax.naming.RefAddr;
030import javax.naming.Reference;
031import javax.naming.spi.ObjectFactory;
032
033import net.sf.hajdbc.DatabaseCluster;
034import net.sf.hajdbc.util.reflect.ProxyFactory;
035
036/**
037 * @author Paul Ferraro
038 *
039 * @param <D>
040 */
041public abstract class CommonDataSourceObjectFactory<D> implements ObjectFactory, CommonDataSourceFactory<D>
042{
043        private Class<D> targetClass;
044        
045        /**
046         * @param targetClass
047         */
048        protected CommonDataSourceObjectFactory(Class<D> targetClass)
049        {
050                this.targetClass = targetClass;
051        }
052
053        /**
054         * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
055         */
056        @Override
057        public Object getObjectInstance(Object object, Name name, Context context, Hashtable<?,?> environment) throws Exception
058        {
059                if ((object == null) || !(object instanceof Reference)) return null;
060                
061                Reference reference = (Reference) object;
062                
063                String className = reference.getClassName();
064                
065                if ((className == null) || !className.equals(this.targetClass.getName())) return null;
066                
067                RefAddr idAddr = reference.get(CommonDataSourceReference.CLUSTER);
068                
069                if (idAddr == null) return null;
070                
071                Object idAddrContent = idAddr.getContent();
072                
073                if ((idAddrContent == null) || !(idAddrContent instanceof String)) return null;
074                
075                String id = (String) idAddrContent;
076                
077                RefAddr configAddr = reference.get(CommonDataSourceReference.CONFIG);
078                
079                String config = null;
080                
081                if (configAddr != null)
082                {
083                        Object configAddrContent = configAddr.getContent();
084                        
085                        if ((configAddrContent != null) && (configAddrContent instanceof String))
086                        {
087                                config = (String) configAddrContent;
088                        }
089                }
090                
091                return this.createProxy(id, config);
092        }
093
094        /**
095         * @see net.sf.hajdbc.sql.CommonDataSourceFactory#createProxy(java.lang.String, java.lang.String)
096         */
097        public D createProxy(String id, String config) throws SQLException
098        {
099                DatabaseCluster<D> cluster = this.getDatabaseCluster(id, config);
100                
101                if (cluster == null) return null;
102                
103                return ProxyFactory.createProxy(this.targetClass, this.getInvocationHandler(cluster));
104        }
105        
106        /**
107         * @param id
108         * @param config
109         * @return the appropriate database cluster
110         * @throws SQLException
111         */
112        protected abstract DatabaseCluster<D> getDatabaseCluster(String id, String config) throws SQLException;
113        
114        /**
115         * @param cluster
116         * @return the appropriate proxy invocation handler for this datasource
117         */
118        protected abstract InvocationHandler getInvocationHandler(DatabaseCluster<D> cluster);
119}