KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mchange > v2 > c3p0 > WrapperConnectionPoolDataSource


1 /*
2  * Distributed as part of c3p0 v.0.9.1
3  *
4  * Copyright (C) 2005 Machinery For Change, Inc.
5  *
6  * Author: Steve Waldman <swaldman@mchange.com>
7  *
8  * This library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License version 2.1, as
10  * published by the Free Software Foundation.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this software; see the file LICENSE. If not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */

22
23
24 package com.mchange.v2.c3p0;
25
26 import java.beans.PropertyChangeEvent JavaDoc;
27 import java.beans.PropertyVetoException JavaDoc;
28 import java.beans.VetoableChangeListener JavaDoc;
29 import java.beans.PropertyChangeListener JavaDoc;
30 import java.io.PrintWriter JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.sql.*;
34 import javax.sql.*;
35 import com.mchange.v2.c3p0.cfg.C3P0Config;
36 import com.mchange.v2.c3p0.impl.*;
37 import com.mchange.v2.log.*;
38
39 // MT: Most methods are left unsynchronized, because getNestedDataSource() is synchronized, and for most methods, that's
40
// the only critical part. Previous oversynchronization led to hangs, when getting the Connection for one Thread happened
41
// to hang, blocking access to getPooledConnection() for all Threads.
42
public final class WrapperConnectionPoolDataSource extends WrapperConnectionPoolDataSourceBase implements ConnectionPoolDataSource
43 {
44     final static MLogger logger = MLog.getLogger( WrapperConnectionPoolDataSource.class );
45
46     //MT: protected by this' lock
47
ConnectionTester connectionTester = C3P0ImplUtils.defaultConnectionTester();
48     Map JavaDoc userOverrides;
49
50     public WrapperConnectionPoolDataSource(boolean autoregister)
51     {
52     super( autoregister );
53
54     setUpPropertyListeners();
55
56     //set up initial value of userOverrides
57
try
58         { this.userOverrides = C3P0ImplUtils.parseUserOverridesAsString( this.getUserOverridesAsString() ); }
59     catch (Exception JavaDoc e)
60         {
61         if ( logger.isLoggable( MLevel.WARNING ) )
62             logger.log( MLevel.WARNING, "Failed to parse stringified userOverrides. " + this.getUserOverridesAsString(), e );
63         }
64     }
65
66     public WrapperConnectionPoolDataSource()
67     { this( true ); }
68
69     private void setUpPropertyListeners()
70     {
71     VetoableChangeListener JavaDoc setConnectionTesterListener = new VetoableChangeListener JavaDoc()
72         {
73         // always called within synchronized mutators of the parent class... needn't explicitly sync here
74
public void vetoableChange( PropertyChangeEvent JavaDoc evt ) throws PropertyVetoException JavaDoc
75         {
76             String JavaDoc propName = evt.getPropertyName();
77             Object JavaDoc val = evt.getNewValue();
78
79             if ( "connectionTesterClassName".equals( propName ) )
80             {
81                 try
82                 { recreateConnectionTester( (String JavaDoc) val ); }
83                 catch ( Exception JavaDoc e )
84                 {
85                     //e.printStackTrace();
86
if ( logger.isLoggable( MLevel.WARNING ) )
87                     logger.log( MLevel.WARNING, "Failed to create ConnectionTester of class " + val, e );
88                     
89                     throw new PropertyVetoException JavaDoc("Could not instantiate connection tester class with name '" + val + "'.", evt);
90                 }
91             }
92             else if ("userOverridesAsString".equals( propName ))
93             {
94                 try
95                 { WrapperConnectionPoolDataSource.this.userOverrides = C3P0ImplUtils.parseUserOverridesAsString( (String JavaDoc) val ); }
96                 catch (Exception JavaDoc e)
97                 {
98                     if ( logger.isLoggable( MLevel.WARNING ) )
99                     logger.log( MLevel.WARNING, "Failed to parse stringified userOverrides. " + val, e );
100                     
101                     throw new PropertyVetoException JavaDoc("Failed to parse stringified userOverrides. " + val, evt);
102                 }
103             }
104         }
105         };
106     this.addVetoableChangeListener( setConnectionTesterListener );
107     }
108
109     public WrapperConnectionPoolDataSource( String JavaDoc configName )
110     {
111     this();
112     
113     try
114         {
115         if (configName != null)
116             C3P0Config.bindNamedConfigToBean( this, configName );
117         }
118     catch (Exception JavaDoc e)
119         {
120         if (logger.isLoggable( MLevel.WARNING ))
121             logger.log( MLevel.WARNING,
122                 "Error binding WrapperConnectionPoolDataSource to named-config '" + configName +
123                 "'. Some default-config values may be used.",
124                 e);
125         }
126     }
127
128     // implementation of javax.sql.ConnectionPoolDataSource
129

130     public PooledConnection getPooledConnection()
131     throws SQLException
132     { return this.getPooledConnection( (ConnectionCustomizer) null, null ); }
133
134     // getNestedDataSource() is sync'ed, which is enough. Unsync'ed this method,
135
// because when sync'ed a hang in retrieving one connection blocks all
136
//
137
protected PooledConnection getPooledConnection( ConnectionCustomizer cc, String JavaDoc pdsIdt )
138     throws SQLException
139     {
140     DataSource nds = getNestedDataSource();
141     if (nds == null)
142         throw new SQLException( "No standard DataSource has been set beneath this wrapper! [ nestedDataSource == null ]");
143     Connection conn = nds.getConnection();
144     if (conn == null)
145         throw new SQLException("An (unpooled) DataSource returned null from its getConnection() method! " +
146                    "DataSource: " + getNestedDataSource());
147     if ( this.isUsesTraditionalReflectiveProxies() )
148         {
149         //return new C3P0PooledConnection( new com.mchange.v2.c3p0.test.CloseReportingConnection( conn ),
150
return new C3P0PooledConnection( conn,
151                          connectionTester,
152                          this.isAutoCommitOnClose(),
153                          this.isForceIgnoreUnresolvedTransactions(),
154                          cc,
155                          pdsIdt);
156         }
157     else
158         {
159         return new NewPooledConnection( conn,
160                         connectionTester,
161                         this.isAutoCommitOnClose(),
162                         this.isForceIgnoreUnresolvedTransactions(),
163                         this.getPreferredTestQuery(),
164                         cc,
165                         pdsIdt);
166         }
167     }
168  
169     public PooledConnection getPooledConnection(String JavaDoc user, String JavaDoc password)
170     throws SQLException
171     { return this.getPooledConnection( user, password, null, null ); }
172
173     // getNestedDataSource() is sync'ed, which is enough. Unsync'ed this method,
174
// because when sync'ed a hang in retrieving one connection blocks all
175
//
176
protected PooledConnection getPooledConnection(String JavaDoc user, String JavaDoc password, ConnectionCustomizer cc, String JavaDoc pdsIdt)
177     throws SQLException
178     {
179     DataSource nds = getNestedDataSource();
180     if (nds == null)
181         throw new SQLException( "No standard DataSource has been set beneath this wrapper! [ nestedDataSource == null ]");
182     Connection conn = nds.getConnection(user, password);
183     if (conn == null)
184         throw new SQLException("An (unpooled) DataSource returned null from its getConnection() method! " +
185                    "DataSource: " + getNestedDataSource());
186     if ( this.isUsesTraditionalReflectiveProxies() )
187         {
188         //return new C3P0PooledConnection( new com.mchange.v2.c3p0.test.CloseReportingConnection( conn ),
189
return new C3P0PooledConnection( conn,
190                          connectionTester,
191                          this.isAutoCommitOnClose(),
192                          this.isForceIgnoreUnresolvedTransactions(),
193                          cc,
194                          pdsIdt);
195         }
196     else
197         {
198         return new NewPooledConnection( conn,
199                         connectionTester,
200                         this.isAutoCommitOnClose(),
201                         this.isForceIgnoreUnresolvedTransactions(),
202                         this.getPreferredTestQuery(),
203                         cc,
204                         pdsIdt);
205         }
206     }
207  
208     public PrintWriter JavaDoc getLogWriter()
209     throws SQLException
210     { return getNestedDataSource().getLogWriter(); }
211
212     public void setLogWriter(PrintWriter JavaDoc out)
213     throws SQLException
214     { getNestedDataSource().setLogWriter( out ); }
215
216     public void setLoginTimeout(int seconds)
217     throws SQLException
218     { getNestedDataSource().setLoginTimeout( seconds ); }
219
220     public int getLoginTimeout()
221     throws SQLException
222     { return getNestedDataSource().getLoginTimeout(); }
223
224     //"virtual properties"
225

226     public String JavaDoc getUser()
227     {
228     try { return C3P0ImplUtils.findAuth( this.getNestedDataSource() ).getUser(); }
229     catch (SQLException e)
230         {
231         //e.printStackTrace();
232
if ( logger.isLoggable( MLevel.WARNING ) )
233             logger.log( MLevel.WARNING,
234                 "An Exception occurred while trying to find the 'user' property from our nested DataSource." +
235                 " Defaulting to no specified username.", e );
236         return null;
237         }
238     }
239
240     public String JavaDoc getPassword()
241     {
242     try { return C3P0ImplUtils.findAuth( this.getNestedDataSource() ).getPassword(); }
243     catch (SQLException e)
244         {
245         //e.printStackTrace();
246
if ( logger.isLoggable( MLevel.WARNING ) )
247             logger.log( MLevel.WARNING, "An Exception occurred while trying to find the 'password' property from our nested DataSource." +
248                 " Defaulting to no specified password.", e );
249         return null;
250         }
251     }
252
253     public Map JavaDoc getUserOverrides()
254     { return userOverrides; }
255
256     public String JavaDoc toString()
257     {
258     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
259     sb.append( super.toString() );
260
261 // if (userOverrides != null)
262
// sb.append("; userOverrides: " + userOverrides.toString());
263

264     return sb.toString();
265     }
266
267     protected String JavaDoc extraToStringInfo()
268     {
269     if (userOverrides != null)
270         return "; userOverrides: " + userOverrides.toString();
271     else
272         return null;
273     }
274
275     //other code
276
private synchronized void recreateConnectionTester(String JavaDoc className) throws Exception JavaDoc
277     {
278     if (className != null)
279         {
280         ConnectionTester ct = (ConnectionTester) Class.forName( className ).newInstance();
281         this.connectionTester = ct;
282         }
283     else
284         this.connectionTester = C3P0ImplUtils.defaultConnectionTester();
285     }
286 }
287
Popular Tags