/*
 * Distributed as part of c3p0 v.0.9.5.3
 *
 * Copyright (C) 2018 Machinery For Change, Inc.
 *
 * Author: Steve Waldman <swaldman@mchange.com>
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of EITHER:
 *
 *     1) The GNU Lesser General Public License (LGPL), version 2.1, as 
 *        published by the Free Software Foundation
 *
 * OR
 *
 *     2) The Eclipse Public License (EPL), version 1.0
 *
 * You may choose which license to accept if you wish to redistribute
 * or modify this work. You may offer derivatives of this work
 * under the license you have chosen, or you may provide the same
 * choice of license which you have been offered here.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received copies of both LGPL v2.1 and EPL v1.0
 * along with this software; see the files LICENSE-EPL and LICENSE-LGPL.
 * If not, the text of these licenses are currently available at
 *
 * LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *  EPL v1.0: http://www.eclipse.org/org/documents/epl-v10.php 
 * 
 */

package com.mchange.v2.c3p0;

import java.beans.*;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.naming.*;
import com.mchange.v2.log.*;
import com.mchange.v2.naming.*;
import com.mchange.v2.c3p0.impl.*;

import javax.sql.DataSource;
import com.mchange.v2.beans.BeansUtils;
import com.mchange.v2.c3p0.cfg.C3P0Config;
import com.mchange.v2.lang.ObjectUtils;

For the meaning of most of these properties, please see c3p0's top-level documentation!

/** * <p>For the meaning of most of these properties, please see c3p0's top-level documentation!</p> */
public abstract class AbstractComboPooledDataSource extends AbstractPoolBackedDataSource implements PooledDataSource, Serializable, Referenceable { final static MLogger logger = MLog.getLogger( AbstractComboPooledDataSource.class ); final static Set TO_STRING_IGNORE_PROPS = new HashSet( Arrays.asList( new String[] { "connection", "lastAcquisitionFailureDefaultUser", "lastCheckinFailureDefaultUser", "lastCheckoutFailureDefaultUser", "lastConnectionTestFailureDefaultUser", "lastIdleTestFailureDefaultUser", "logWriter", "loginTimeout", "numBusyConnections", "numBusyConnectionsAllUsers", "numBusyConnectionsDefaultUser", "numConnections", "numConnectionsAllUsers", "numConnectionsDefaultUser", "numFailedCheckinsDefaultUser", "numFailedCheckoutsDefaultUser", "numFailedIdleTestsDefaultUser", "numIdleConnections", "numIdleConnectionsAllUsers", "numThreadsAwaitingCheckoutDefaultUser", "numIdleConnectionsDefaultUser", "numUnclosedOrphanedConnections", "numUnclosedOrphanedConnectionsAllUsers", "numUnclosedOrphanedConnectionsDefaultUser", "numUserPools", "effectivePropertyCycleDefaultUser", "parentLogger", "startTimeMillisDefaultUser", "statementCacheNumCheckedOutDefaultUser", "statementCacheNumCheckedOutStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsDefaultUser", "statementCacheNumStatementsAllUsers", "statementCacheNumStatementsDefaultUser", "statementDestroyerNumConnectionsInUseAllUsers", "statementDestroyerNumConnectionsWithDeferredDestroyStatementsAllUsers", "statementDestroyerNumDeferredDestroyStatementsAllUsers", "statementDestroyerNumConnectionsInUseDefaultUser", "statementDestroyerNumConnectionsWithDeferredDestroyStatementsDefaultUser", "statementDestroyerNumDeferredDestroyStatementsDefaultUser", "statementDestroyerNumThreads", "statementDestroyerNumActiveThreads", "statementDestroyerNumIdleThreads", "statementDestroyerNumTasksPending", "threadPoolSize", "threadPoolNumActiveThreads", "threadPoolNumIdleThreads", "threadPoolNumTasksPending", "threadPoolStackTraces", "threadPoolStatus", "overrideDefaultUser", "overrideDefaultPassword", "password", "reference", "upTimeMillisDefaultUser", "user", "userOverridesAsString", "allUsers", "connectionPoolDataSource", "propertyChangeListeners", "vetoableChangeListeners" } ) ); // just so we have a unified syntax when we guard against degenerate parameter changes, which // otherwise might needlessly reset pools. private static boolean diff( int a, int b ) { return a != b; } private static boolean diff( boolean a, boolean b ) { return a != b; } private static boolean diff( Object a, Object b ) { return !ObjectUtils.eqOrBothNull(a, b ); } // not reassigned post-ctor; mutable elements protected by their own locks // when (very rarely) necessery, we sync this -> wcpds -> dmds // note that serialization of these guys happens via our superclass // we just have to make sure they get properly reset on deserialization transient DriverManagerDataSource dmds; transient WrapperConnectionPoolDataSource wcpds; public AbstractComboPooledDataSource() { this( true ); } public AbstractComboPooledDataSource( boolean autoregister ) { super( autoregister ); // System.err.println("...Initializing ComboPooledDataSource."); dmds = new DriverManagerDataSource(); wcpds = new WrapperConnectionPoolDataSource(); wcpds.setNestedDataSource( dmds ); try { this.setConnectionPoolDataSource( wcpds ); } catch (PropertyVetoException e) { logger.log(MLevel.WARNING, "Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet!", e); throw new RuntimeException("Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet! " + e); } // set things up in case there are future changes to our ConnectionPoolDataSource // setUpPropertyEvents(); } private void setUpPropertyEvents() { VetoableChangeListener wcpdsConsistencyEnforcer = new VetoableChangeListener() { // always called within synchronized mutators of the parent class... needn't explicitly sync here public void vetoableChange( PropertyChangeEvent evt ) throws PropertyVetoException { String propName = evt.getPropertyName(); Object val = evt.getNewValue(); if ( "connectionPoolDataSource".equals( propName ) ) { if (val instanceof WrapperConnectionPoolDataSource) { DataSource nested = (DataSource) ((WrapperConnectionPoolDataSource)val).getNestedDataSource(); if (! (nested instanceof DriverManagerDataSource) ) throw new PropertyVetoException(this.getClass().getName() + " requires that its unpooled DataSource " + " be set at all times, and that it be a" + " com.mchange.v2.c3p0.DriverManagerDataSource. Bad: " + nested, evt); } else throw new PropertyVetoException(this.getClass().getName() + " requires that its ConnectionPoolDataSource " + " be set at all times, and that it be a" + " com.mchange.v2.c3p0.WrapperConnectionPoolDataSource. Bad: " + val, evt); } } }; this.addVetoableChangeListener( wcpdsConsistencyEnforcer ); PropertyChangeListener wcpdsStateUpdater = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { String propName = evt.getPropertyName(); Object val = evt.getNewValue(); if ( "connectionPoolDataSource".equals( propName ) ) updateLocalVarsFromCpdsProp(); } }; this.addPropertyChangeListener( wcpdsStateUpdater ); } private void updateLocalVarsFromCpdsProp() { this.wcpds = (WrapperConnectionPoolDataSource) this.getConnectionPoolDataSource(); this.dmds = (DriverManagerDataSource) wcpds.getNestedDataSource(); } public AbstractComboPooledDataSource(String configName) { this(); initializeNamedConfig( configName, true ); } // // workaround sun big id #6342411 (in which reflective // // access to a public method of a non-public class fails, // // even if the non-public class is accessed via a public // // subclass) // public String getDataSourceName() // { return super.getDataSourceName(); } // DriverManagerDataSourceProperties (count: 4) public String getDescription() { return dmds.getDescription(); } public void setDescription( String description ) { dmds.setDescription( description ); } public String getDriverClass() { return dmds.getDriverClass(); } public void setDriverClass( String driverClass ) throws PropertyVetoException { dmds.setDriverClass( driverClass ); // System.err.println("setting driverClass: " + driverClass); } public boolean isForceUseNamedDriverClass() { return dmds.isForceUseNamedDriverClass(); } public void setForceUseNamedDriverClass( boolean forceUseNamedDriverClass ) { dmds.setForceUseNamedDriverClass( forceUseNamedDriverClass ); } public String getJdbcUrl() { // System.err.println("getting jdbcUrl: " + dmds.getJdbcUrl()); return dmds.getJdbcUrl(); } public void setJdbcUrl( String jdbcUrl ) { if ( diff( dmds.getJdbcUrl(), jdbcUrl ) ) { dmds.setJdbcUrl( jdbcUrl ); this.resetPoolManager( false ); // System.err.println("setting jdbcUrl: " + jdbcUrl + " [dmds@" + C3P0ImplUtils.identityToken( dmds ) + "]"); // if (jdbcUrl == null) // new Exception("*** NULL SETTER ***").printStackTrace(); } } public Properties getProperties() { //System.err.println("getting properties: " + dmds.getProperties()); return dmds.getProperties(); } public void setProperties( Properties properties ) { if ( diff( dmds.getProperties(), properties ) ) { //System.err.println("setting properties: " + properties); dmds.setProperties( properties ); this.resetPoolManager(false); } } // DriverManagerDataSource "virtual properties" based on properties public String getUser() { return dmds.getUser(); } public void setUser( String user ) { if ( diff( dmds.getUser(), user ) ) { dmds.setUser( user ); this.resetPoolManager( false ); } } public String getPassword() { return dmds.getPassword(); } public void setPassword( String password ) { if ( diff( dmds.getPassword(), password ) ) { dmds.setPassword( password ); this.resetPoolManager( false ); } } // WrapperConnectionPoolDataSource properties public int getCheckoutTimeout() { return wcpds.getCheckoutTimeout(); } public void setCheckoutTimeout( int checkoutTimeout ) { if ( diff( wcpds.getCheckoutTimeout(), checkoutTimeout ) ) { wcpds.setCheckoutTimeout( checkoutTimeout ); this.resetPoolManager( false ); } } public int getAcquireIncrement() { return wcpds.getAcquireIncrement(); } public void setAcquireIncrement( int acquireIncrement ) { if ( diff( wcpds.getAcquireIncrement(), acquireIncrement ) ) { wcpds.setAcquireIncrement( acquireIncrement ); this.resetPoolManager( false ); } } public int getAcquireRetryAttempts() { return wcpds.getAcquireRetryAttempts(); } public void setAcquireRetryAttempts( int acquireRetryAttempts ) { if ( diff( wcpds.getAcquireRetryAttempts(), acquireRetryAttempts ) ) { wcpds.setAcquireRetryAttempts( acquireRetryAttempts ); this.resetPoolManager( false ); } } public int getAcquireRetryDelay() { return wcpds.getAcquireRetryDelay(); } public void setAcquireRetryDelay( int acquireRetryDelay ) { if ( diff( wcpds.getAcquireRetryDelay(), acquireRetryDelay ) ) { wcpds.setAcquireRetryDelay( acquireRetryDelay ); this.resetPoolManager( false ); } } public boolean isAutoCommitOnClose() { return wcpds.isAutoCommitOnClose(); } public void setAutoCommitOnClose( boolean autoCommitOnClose ) { if ( diff(wcpds.isAutoCommitOnClose(), autoCommitOnClose) ) { wcpds.setAutoCommitOnClose( autoCommitOnClose ); this.resetPoolManager( false ); } } public String getContextClassLoaderSource() { return wcpds.getContextClassLoaderSource(); } public void setContextClassLoaderSource( String contextClassLoaderSource ) throws PropertyVetoException { if ( diff( wcpds.getContextClassLoaderSource(), contextClassLoaderSource ) ) { wcpds.setContextClassLoaderSource( contextClassLoaderSource ); this.resetPoolManager( false ); } } public String getConnectionTesterClassName() { return wcpds.getConnectionTesterClassName(); } public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException { if ( diff( wcpds.getConnectionTesterClassName(), connectionTesterClassName ) ) { wcpds.setConnectionTesterClassName( connectionTesterClassName ); this.resetPoolManager( false ); } } public String getAutomaticTestTable() { return wcpds.getAutomaticTestTable(); } public void setAutomaticTestTable( String automaticTestTable ) { if ( diff( wcpds.getAutomaticTestTable(), automaticTestTable ) ) { wcpds.setAutomaticTestTable( automaticTestTable ); this.resetPoolManager( false ); } } public boolean isForceIgnoreUnresolvedTransactions() { return wcpds.isForceIgnoreUnresolvedTransactions(); } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) { if ( diff( wcpds.isForceIgnoreUnresolvedTransactions(), forceIgnoreUnresolvedTransactions ) ) { wcpds.setForceIgnoreUnresolvedTransactions( forceIgnoreUnresolvedTransactions ); this.resetPoolManager( false ); } } public boolean isPrivilegeSpawnedThreads() { return wcpds.isPrivilegeSpawnedThreads(); } public void setPrivilegeSpawnedThreads( boolean privilegeSpawnedThreads ) { if ( diff( wcpds.isPrivilegeSpawnedThreads(), privilegeSpawnedThreads ) ) { wcpds.setPrivilegeSpawnedThreads( privilegeSpawnedThreads ); this.resetPoolManager( false ); } } public int getIdleConnectionTestPeriod() { return wcpds.getIdleConnectionTestPeriod(); } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) { if ( diff( wcpds.getIdleConnectionTestPeriod(), idleConnectionTestPeriod ) ) { wcpds.setIdleConnectionTestPeriod( idleConnectionTestPeriod ); this.resetPoolManager( false ); } } public int getInitialPoolSize() { return wcpds.getInitialPoolSize(); } public void setInitialPoolSize( int initialPoolSize ) { if ( diff( wcpds.getInitialPoolSize(), initialPoolSize ) ) { wcpds.setInitialPoolSize( initialPoolSize ); this.resetPoolManager( false ); } } public int getMaxIdleTime() { return wcpds.getMaxIdleTime(); } public void setMaxIdleTime( int maxIdleTime ) { if ( diff( wcpds.getMaxIdleTime(), maxIdleTime ) ) { wcpds.setMaxIdleTime( maxIdleTime ); this.resetPoolManager( false ); } } public int getMaxPoolSize() { return wcpds.getMaxPoolSize(); } public void setMaxPoolSize( int maxPoolSize ) { if ( diff( wcpds.getMaxPoolSize(), maxPoolSize ) ) { wcpds.setMaxPoolSize( maxPoolSize ); this.resetPoolManager( false ); } } public int getMaxStatements() { return wcpds.getMaxStatements(); } public void setMaxStatements( int maxStatements ) { if ( diff( wcpds.getMaxStatements(), maxStatements ) ) { wcpds.setMaxStatements( maxStatements ); this.resetPoolManager( false ); } } public int getMaxStatementsPerConnection() { return wcpds.getMaxStatementsPerConnection(); } public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) { if ( diff( wcpds.getMaxStatementsPerConnection(), maxStatementsPerConnection ) ) { wcpds.setMaxStatementsPerConnection( maxStatementsPerConnection ); this.resetPoolManager( false ); } } public int getMinPoolSize() { return wcpds.getMinPoolSize(); } public void setMinPoolSize( int minPoolSize ) { if ( diff( wcpds.getMinPoolSize(), minPoolSize ) ) { wcpds.setMinPoolSize( minPoolSize ); this.resetPoolManager( false ); } } public String getOverrideDefaultUser() { return wcpds.getOverrideDefaultUser(); } public void setOverrideDefaultUser(String overrideDefaultUser) { if ( diff( wcpds.getOverrideDefaultUser(), overrideDefaultUser ) ) { wcpds.setOverrideDefaultUser( overrideDefaultUser ); this.resetPoolManager( false ); } } public String getOverrideDefaultPassword() { return wcpds.getOverrideDefaultPassword(); } public void setOverrideDefaultPassword(String overrideDefaultPassword) { if ( diff( wcpds.getOverrideDefaultPassword(), overrideDefaultPassword ) ) { wcpds.setOverrideDefaultPassword( overrideDefaultPassword ); this.resetPoolManager( false ); } } public int getPropertyCycle() { return wcpds.getPropertyCycle(); } public void setPropertyCycle( int propertyCycle ) { if ( diff( wcpds.getPropertyCycle(), propertyCycle ) ) { wcpds.setPropertyCycle( propertyCycle ); this.resetPoolManager( false ); } } public boolean isBreakAfterAcquireFailure() { return wcpds.isBreakAfterAcquireFailure(); } public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) { if ( diff( wcpds.isBreakAfterAcquireFailure(), breakAfterAcquireFailure ) ) { wcpds.setBreakAfterAcquireFailure( breakAfterAcquireFailure ); this.resetPoolManager( false ); } } public boolean isTestConnectionOnCheckout() { return wcpds.isTestConnectionOnCheckout(); } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) { if ( diff( wcpds.isTestConnectionOnCheckout(), testConnectionOnCheckout ) ) { wcpds.setTestConnectionOnCheckout( testConnectionOnCheckout ); this.resetPoolManager( false ); } } public boolean isTestConnectionOnCheckin() { return wcpds.isTestConnectionOnCheckin(); } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) { if ( diff( wcpds.isTestConnectionOnCheckin(), testConnectionOnCheckin ) ) { wcpds.setTestConnectionOnCheckin( testConnectionOnCheckin ); this.resetPoolManager( false ); } } public boolean isUsesTraditionalReflectiveProxies() { return wcpds.isUsesTraditionalReflectiveProxies(); } public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) { if ( diff( wcpds.isUsesTraditionalReflectiveProxies(), usesTraditionalReflectiveProxies ) ) { wcpds.setUsesTraditionalReflectiveProxies( usesTraditionalReflectiveProxies ); this.resetPoolManager( false ); } } public String getPreferredTestQuery() { return wcpds.getPreferredTestQuery(); } public void setPreferredTestQuery( String preferredTestQuery ) { if ( diff( wcpds.getPreferredTestQuery(), preferredTestQuery ) ) { wcpds.setPreferredTestQuery( preferredTestQuery ); this.resetPoolManager( false ); } } public int getMaxAdministrativeTaskTime() { return wcpds.getMaxAdministrativeTaskTime(); } public void setMaxAdministrativeTaskTime( int maxAdministrativeTaskTime ) { if ( diff( wcpds.getMaxAdministrativeTaskTime(), maxAdministrativeTaskTime ) ) { wcpds.setMaxAdministrativeTaskTime( maxAdministrativeTaskTime ); this.resetPoolManager( false ); } } public int getMaxIdleTimeExcessConnections() { return wcpds.getMaxIdleTimeExcessConnections(); } public void setMaxIdleTimeExcessConnections( int maxIdleTimeExcessConnections ) { if ( diff( wcpds.getMaxIdleTimeExcessConnections(), maxIdleTimeExcessConnections ) ) { wcpds.setMaxIdleTimeExcessConnections( maxIdleTimeExcessConnections ); this.resetPoolManager( false ); } } public int getMaxConnectionAge() { return wcpds.getMaxConnectionAge(); } public void setMaxConnectionAge( int maxConnectionAge ) { if ( diff( wcpds.getMaxConnectionAge(), maxConnectionAge ) ) { wcpds.setMaxConnectionAge( maxConnectionAge ); this.resetPoolManager( false ); } } public String getConnectionCustomizerClassName() { return wcpds.getConnectionCustomizerClassName(); } public void setConnectionCustomizerClassName( String connectionCustomizerClassName ) { if ( diff( wcpds.getConnectionCustomizerClassName(), connectionCustomizerClassName ) ) { wcpds.setConnectionCustomizerClassName( connectionCustomizerClassName ); this.resetPoolManager( false ); } } public int getUnreturnedConnectionTimeout() { return wcpds.getUnreturnedConnectionTimeout(); } public void setUnreturnedConnectionTimeout(int unreturnedConnectionTimeout) { if ( diff( wcpds.getUnreturnedConnectionTimeout(), unreturnedConnectionTimeout ) ) { wcpds.setUnreturnedConnectionTimeout( unreturnedConnectionTimeout ); this.resetPoolManager( false ); } } public String getUserOverridesAsString() { return wcpds.getUserOverridesAsString(); } public void setUserOverridesAsString(String uoas) throws PropertyVetoException { if ( diff( wcpds.getUserOverridesAsString(), uoas ) ) { wcpds.setUserOverridesAsString( uoas ); this.resetPoolManager( false ); } } public Map getUserOverrides() { return wcpds.getUserOverrides(); } public boolean isDebugUnreturnedConnectionStackTraces() { return wcpds.isDebugUnreturnedConnectionStackTraces(); } public void setDebugUnreturnedConnectionStackTraces(boolean debugUnreturnedConnectionStackTraces) { if ( diff( wcpds.isDebugUnreturnedConnectionStackTraces(), debugUnreturnedConnectionStackTraces ) ) { wcpds.setDebugUnreturnedConnectionStackTraces( debugUnreturnedConnectionStackTraces ); this.resetPoolManager( false ); } } public boolean isForceSynchronousCheckins() { return wcpds.isForceSynchronousCheckins(); } public void setForceSynchronousCheckins(boolean forceSynchronousCheckins) { if ( diff( wcpds.isForceSynchronousCheckins(), forceSynchronousCheckins ) ) { wcpds.setForceSynchronousCheckins( forceSynchronousCheckins ); this.resetPoolManager( false ); } } public int getStatementCacheNumDeferredCloseThreads() { return wcpds.getStatementCacheNumDeferredCloseThreads(); } public void setStatementCacheNumDeferredCloseThreads(int statementCacheNumDeferredCloseThreads) { if ( diff( wcpds.getStatementCacheNumDeferredCloseThreads(), statementCacheNumDeferredCloseThreads ) ) { wcpds.setStatementCacheNumDeferredCloseThreads( statementCacheNumDeferredCloseThreads ); this.resetPoolManager( false ); } } // shared properties (count: 1) public String getFactoryClassLocation() { return super.getFactoryClassLocation(); } public void setFactoryClassLocation( String factoryClassLocation ) { if ( diff( dmds.getFactoryClassLocation(), factoryClassLocation ) || diff( wcpds.getFactoryClassLocation(), factoryClassLocation ) || diff( super.getFactoryClassLocation(), factoryClassLocation ) ) { dmds.setFactoryClassLocation( factoryClassLocation ); wcpds.setFactoryClassLocation( factoryClassLocation ); super.setFactoryClassLocation( factoryClassLocation ); } } public String toString() { return toString( false ); } public String toString(boolean show_config) { if ( show_config ) { //System.err.println("ComboPooledDataSource.toString()"); StringBuffer sb = new StringBuffer(512); sb.append( this.getClass().getName() ); sb.append(" [ "); try { BeansUtils.appendPropNamesAndValues(sb, this, TO_STRING_IGNORE_PROPS); } catch (Exception e) { sb.append( e.toString() ); //e.printStackTrace(); } sb.append(" ]"); // Map userOverrides = wcpds.getUserOverrides(); // if (userOverrides != null) // sb.append("; userOverrides: " + userOverrides.toString()); return sb.toString(); } else { return this.getClass().getName() + "[ identityToken -> " + this.getIdentityToken() + ", dataSourceName -> " + this.getDataSourceName() + " ]"; } } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: updateLocalVarsFromCpdsProp(); setUpPropertyEvents(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } // JDBC4 Wrapper stuff private boolean isWrapperForDmds(Class<?> iface) { return iface.isAssignableFrom( dmds.getClass() ); } public boolean isWrapperFor(Class<?> iface) throws SQLException { return isWrapperForDmds( iface ) || isWrapperForThis( iface ); } public <T> T unwrap(Class<T> iface) throws SQLException { if (this.isWrapperForDmds( iface )) return dmds.unwrap( iface ); else if ( this.isWrapperForThis( iface ) ) return (T) this; else throw new SQLException(this + " is not a wrapper for or implementation of " + iface.getName()); } } //now, referenceability happens exactly the same way it does for PoolBackedDataSource //all this stuff (and the maintenance hassle of it) should be unnecessary /* // WrapperConnectionPoolDataSource properties -- count: 28 // // ("checkoutTimeout"); // ("acquireIncrement"); // ("acquireRetryAttempts"); // ("acquireRetryDelay"); // ("autoCommitOnClose"); // ("connectionTesterClassName"); // ("forceIgnoreUnresolvedTransactions"); // ("idleConnectionTestPeriod"); // ("initialPoolSize"); // ("maxIdleTime"); // ("maxPoolSize"); // ("maxStatements"); // ("maxStatementsPerConnection"); // ("minPoolSize"); // ("propertyCycle"); // ("breakAfterAcquireFailure"); // ("testConnectionOnCheckout"); // ("testConnectionOnCheckin"); // ("usesTraditionalReflectiveProxies"); // ("preferredTestQuery"); // ("automaticTestTable"); // ("userOverridesAsString"); // ("overrideDefaultUser"); // ("overrideDefaultPassword"); // ("maxAdministrativeTaskTime"); // ("maxIdleTimeExcessConnections"); // ("maxConnectionAge"); // ("connectionTesterClassName"); final static JavaBeanReferenceMaker referenceMaker = new JavaBeanReferenceMaker(); static { referenceMaker.setFactoryClassName( C3P0JavaBeanObjectFactory.class.getName() ); // DriverManagerDataSource properties (count: 4) referenceMaker.addReferenceProperty("description"); referenceMaker.addReferenceProperty("driverClass"); referenceMaker.addReferenceProperty("jdbcUrl"); referenceMaker.addReferenceProperty("properties"); // WrapperConnectionPoolDataSource properties (count: 27) referenceMaker.addReferenceProperty("checkoutTimeout"); referenceMaker.addReferenceProperty("acquireIncrement"); referenceMaker.addReferenceProperty("acquireRetryAttempts"); referenceMaker.addReferenceProperty("acquireRetryDelay"); referenceMaker.addReferenceProperty("autoCommitOnClose"); referenceMaker.addReferenceProperty("connectionTesterClassName"); referenceMaker.addReferenceProperty("forceIgnoreUnresolvedTransactions"); referenceMaker.addReferenceProperty("idleConnectionTestPeriod"); referenceMaker.addReferenceProperty("initialPoolSize"); referenceMaker.addReferenceProperty("maxIdleTime"); referenceMaker.addReferenceProperty("maxPoolSize"); referenceMaker.addReferenceProperty("maxStatements"); referenceMaker.addReferenceProperty("maxStatementsPerConnection"); referenceMaker.addReferenceProperty("minPoolSize"); referenceMaker.addReferenceProperty("propertyCycle"); referenceMaker.addReferenceProperty("breakAfterAcquireFailure"); referenceMaker.addReferenceProperty("testConnectionOnCheckout"); referenceMaker.addReferenceProperty("testConnectionOnCheckin"); referenceMaker.addReferenceProperty("usesTraditionalReflectiveProxies"); referenceMaker.addReferenceProperty("preferredTestQuery"); referenceMaker.addReferenceProperty("automaticTestTable"); referenceMaker.addReferenceProperty("userOverridesAsString"); referenceMaker.addReferenceProperty("overrideDefaultUser"); referenceMaker.addReferenceProperty("overrideDefaultPassword"); referenceMaker.addReferenceProperty("maxAdministrativeTaskTime"); referenceMaker.addReferenceProperty("maxIdleTimeExcessConnections"); referenceMaker.addReferenceProperty("maxConnectionAge"); // PoolBackedDataSource properties (count: 2) referenceMaker.addReferenceProperty("dataSourceName"); referenceMaker.addReferenceProperty("numHelperThreads"); // identity token referenceMaker.addReferenceProperty("identityToken"); // shared properties (count: 1) referenceMaker.addReferenceProperty("factoryClassLocation"); } public Reference getReference() throws NamingException { synchronized ( this ) { synchronized ( wcpds ) { synchronized( dmds ) { //System.err.println("ComboPooledDataSource.getReference()!!!!"); //new Exception("PRINT-STACK-TRACE").printStackTrace(); //javax.naming.Reference out = referenceMaker.createReference( this ); //System.err.println(out); //return out; return referenceMaker.createReference( this ); } } } } */