package org.jdbcdslog; import java.io.PrintWriter; import java.io.Serializable; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import javax.sql.PooledConnection; import javax.sql.XAConnection; import javax.sql.XADataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DataSourceProxyBase implements Serializable { static Logger logger = LoggerFactory.getLogger(DataSourceProxyBase.class); static final String targetDSParameter = "targetDS"; Object targetDS = null; Map props = new HashMap(); Map propClasses = new HashMap(); public DataSourceProxyBase() throws JDBCDSLogException { } public Connection getConnection() throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof DataSource) { Connection con = ((DataSource)targetDS).getConnection(); if(ConnectionLogger.logger.isInfoEnabled()) ConnectionLogger.logger.info("connect to URL " + con.getMetaData().getURL() + " for user " + con.getMetaData().getUserName()); return ConnectionLoggingProxy.wrap(con); } else throw new SQLException("targetDS doesn't implement DataSource interface."); } public Connection getConnection(String username, String password) throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof DataSource) { Connection con = ((DataSource)targetDS).getConnection(username, password); if(ConnectionLogger.logger.isInfoEnabled()) ConnectionLogger.logger.info("connect to URL " + con.getMetaData().getURL() + " for user " + con.getMetaData().getUserName()); return ConnectionLoggingProxy.wrap(con); } else throw new SQLException("targetDS doesn't implement DataSource interface."); } public PrintWriter getLogWriter() throws SQLException { if(targetDS instanceof DataSource) return ((DataSource)targetDS).getLogWriter(); if(targetDS instanceof XADataSource) return ((XADataSource)targetDS).getLogWriter(); if(targetDS instanceof ConnectionPoolDataSource) return ((ConnectionPoolDataSource)targetDS).getLogWriter(); throw new SQLException("targetDS doesn't have getLogWriter() method"); } public int getLoginTimeout() throws SQLException { if(targetDS instanceof DataSource) return ((DataSource)targetDS).getLoginTimeout(); if(targetDS instanceof XADataSource) return ((XADataSource)targetDS).getLoginTimeout(); if(targetDS instanceof ConnectionPoolDataSource) return ((ConnectionPoolDataSource)targetDS).getLoginTimeout(); throw new SQLException("targetDS doesn't have getLogTimeout() method"); } public void setLogWriter(PrintWriter out) throws SQLException { if(targetDS instanceof DataSource) ((DataSource)targetDS).setLogWriter(out); if(targetDS instanceof XADataSource) ((XADataSource)targetDS).setLogWriter(out); if(targetDS instanceof ConnectionPoolDataSource) ((ConnectionPoolDataSource)targetDS).setLogWriter(out); throw new SQLException("targetDS doesn't have setLogWriter() method"); } public void setLoginTimeout(int seconds) throws SQLException { if(targetDS instanceof DataSource) ((DataSource)targetDS).setLoginTimeout(seconds); if(targetDS instanceof XADataSource) ((XADataSource)targetDS).setLoginTimeout(seconds); if(targetDS instanceof ConnectionPoolDataSource) ((ConnectionPoolDataSource)targetDS).setLoginTimeout(seconds); throw new SQLException("targetDS doesn't have setLogWriter() method"); } public XAConnection getXAConnection() throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof XADataSource) { XAConnection con = ((XADataSource)targetDS).getXAConnection(); return XAConnectionLoggingProxy.wrap(con); } else throw new SQLException("targetDS doesn't implement XADataSource interface."); } public XAConnection getXAConnection(String user, String password) throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof XADataSource) return XAConnectionLoggingProxy.wrap(((XADataSource)targetDS).getXAConnection(user, password)); else throw new SQLException("targetDS doesn't implement XADataSource interface."); } public PooledConnection getPooledConnection() throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof ConnectionPoolDataSource) return PooledConnectionLoggingProxy.wrap(((ConnectionPoolDataSource)targetDS).getPooledConnection()); else throw new SQLException("targetDS doesn't implement ConnectionPoolDataSource interface."); } public PooledConnection getPooledConnection(String user, String password) throws SQLException { if(targetDS == null) throw new SQLException("targetDS parameter has not been passed to Database or URL property."); if(targetDS instanceof ConnectionPoolDataSource) return PooledConnectionLoggingProxy.wrap(((ConnectionPoolDataSource)targetDS).getPooledConnection(user, password)); else throw new SQLException("targetDS doesn't implement ConnectionPoolDataSource interface."); } void invokeTargetSetMethod(String m, Object p, Class c) { String methodName = "invokeTargetSetMethod() "; if(targetDS == null) { props.put(m, p); propClasses.put(m, c); return; } logger.debug(m + "(" + p.toString() + ")"); try { Method me = targetDS.getClass().getMethod(m, new Class[] { c }); if (me != null) me.invoke(targetDS, new Object[] { p }); } catch (Exception e) { ConnectionLogger.logger.error(e.getMessage(), e); } } public void setURL(String url) throws JDBCDSLogException { url = initTargetDS(url); invokeTargetSetMethod("setURL", url, String.class); } private String initTargetDS(String url) throws JDBCDSLogException { String methodName = "initTargedDS() "; logger.debug(methodName + "url = " + url + " targedDS = " + targetDS); try { if(url == null || targetDS != null) return url; logger.debug("Parse url."); StringTokenizer ts = new StringTokenizer(url, ":/;=&?", false); String targetDSName = null; while (ts.hasMoreTokens()) { String s = ts.nextToken(); logger.debug("s = " + s); if (targetDSParameter.equals(s) && ts.hasMoreTokens()) { targetDSName = ts.nextToken(); break; } } if (targetDSName == null) return url; url = url.substring(0, url.length() - targetDSName.length() - targetDSParameter.length() - 2); setTargetDS(targetDSName); return url; } catch (Throwable t) { ConnectionLogger.logger.error(t.getMessage(), t); throw new JDBCDSLogException(t); } } public void setTargetDS(String targetDSName) throws JDBCDSLogException, InstantiationException, IllegalAccessException { String methodName = "setTargetDS() "; try { Class cl = Class.forName(targetDSName); if (cl == null) throw new JDBCDSLogException("Can't load class of targetDS."); Object targetObj = cl.newInstance(); targetDS = targetObj; logger.debug(methodName + "targetDS initialized."); setPropertiesForTargetDS(); } catch(Throwable t) { ConnectionLogger.logger.error(t.getMessage(), t); throw new JDBCDSLogException(t); } } private void setPropertiesForTargetDS() { for(Iterator i = props.keySet().iterator(); i.hasNext(); ) { String m = (String)i.next(); invokeTargetSetMethod(m, props.get(m), (Class)propClasses.get(m)); } } public void setDatabaseName(String p) { invokeTargetSetMethod("setDatabaseName", p, String.class); } public void setDescription(String p) { invokeTargetSetMethod("setDescription", p, String.class); } public void setDataSourceName(String p) { invokeTargetSetMethod("setDataSourceName", p, String.class); } public void setDriverType(String p) { invokeTargetSetMethod("setDriverType", p, String.class); } public void setNetworkProtocol(String p) { invokeTargetSetMethod("setNetworkProtocol", p, String.class); } public void setPassword(String p) { invokeTargetSetMethod("setPassword", p, String.class); } public void setPortNumber(int p) { invokeTargetSetMethod("setPortNumber", new Integer(p), int.class); } public void setServerName(String p) { invokeTargetSetMethod("setServerName", p, String.class); } public void setServiceName(String p) { invokeTargetSetMethod("setServiceName", p, String.class); } public void setTNSEntryName(String p) { invokeTargetSetMethod("setTNSEntryName", p, String.class); } public void setUser(String p) { invokeTargetSetMethod("setUser", p, String.class); } public void setDatabase(String p) throws JDBCDSLogException { p = initTargetDS(p); invokeTargetSetMethod("setDatabase", p, String.class); } public boolean isWrapperFor(Class iface) throws SQLException { return false; } public Object unwrap(Class iface) throws SQLException { return null; } }