KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mchange > v2 > c3p0 > test > FreezableDriverManagerDataSource


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.test;
25
26 import java.beans.PropertyChangeEvent JavaDoc;
27 import java.beans.PropertyChangeListener JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.ObjectInputStream JavaDoc;
31 import java.io.ObjectOutputStream JavaDoc;
32 import java.io.PrintWriter JavaDoc;
33 import java.util.Properties JavaDoc;
34 import java.sql.Connection JavaDoc;
35 import java.sql.Driver JavaDoc;
36 import java.sql.DriverManager JavaDoc;
37 import java.sql.SQLException JavaDoc;
38 import javax.sql.DataSource JavaDoc;
39 import com.mchange.v2.sql.SqlUtils;
40 import com.mchange.v2.log.MLevel;
41 import com.mchange.v2.log.MLog;
42 import com.mchange.v2.log.MLogger;
43 import com.mchange.v2.c3p0.cfg.C3P0Config;
44 import com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase;
45
46
47 // this is a copy-paste hack job to do a quick simulation of how c3p0 responds when
48
// getConnection() freezes but does not fail.
49
public final class FreezableDriverManagerDataSource extends DriverManagerDataSourceBase implements DataSource JavaDoc
50 {
51     final static MLogger logger = MLog.getLogger( FreezableDriverManagerDataSource.class );
52     
53     final static File JavaDoc FREEZE_FILE = new File JavaDoc("/tmp/c3p0_freeze_file");
54
55     //MT: protected by this' lock
56
Driver JavaDoc driver;
57     
58     //MT: protected by this' lock
59
boolean driver_class_loaded = false;
60
61     public FreezableDriverManagerDataSource()
62     { this( true ); }
63
64     public FreezableDriverManagerDataSource(boolean autoregister)
65     {
66         super( autoregister );
67
68         setUpPropertyListeners();
69
70         String JavaDoc user = C3P0Config.initializeStringPropertyVar("user", null);
71         String JavaDoc password = C3P0Config.initializeStringPropertyVar("password", null);
72
73         if (user != null)
74             this.setUser( user );
75
76         if (password != null)
77             this.setPassword( password );
78     }
79     
80     private void waitNoFreezeFile() throws SQLException JavaDoc
81     {
82         try
83         {
84             while (true)
85             {
86                 if (! FREEZE_FILE.exists())
87                     break;
88                 Thread.sleep(1000);
89             }
90         }
91         catch (InterruptedException JavaDoc e)
92         {
93             logger.log(MLevel.WARNING, "Frozen cxn acquire interrupted.", e);
94             throw new SQLException JavaDoc( e.toString() );
95         }
96     }
97
98     private void setUpPropertyListeners()
99     {
100         PropertyChangeListener JavaDoc driverClassListener = new PropertyChangeListener JavaDoc()
101         {
102             public void propertyChange( PropertyChangeEvent JavaDoc evt )
103             {
104                 Object JavaDoc val = evt.getNewValue();
105                 if ( "driverClass".equals( evt.getPropertyName() ) )
106                     setDriverClassLoaded( false );
107             }
108         };
109         this.addPropertyChangeListener( driverClassListener );
110     }
111     
112     private synchronized boolean isDriverClassLoaded()
113     { return driver_class_loaded; }
114     
115     private synchronized void setDriverClassLoaded(boolean dcl)
116     { this.driver_class_loaded = dcl; }
117     
118     private void ensureDriverLoaded() throws SQLException JavaDoc
119     {
120         try
121         {
122             if (! isDriverClassLoaded())
123             {
124                 if (driverClass != null)
125                     Class.forName( driverClass );
126                 setDriverClassLoaded( true );
127             }
128         }
129         catch (ClassNotFoundException JavaDoc e)
130         {
131             if (logger.isLoggable(MLevel.WARNING))
132                 logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e);
133         }
134     }
135
136     // should NOT be sync'ed -- driver() is sync'ed and that's enough
137
// sync'ing the method creates the danger that one freeze on connect
138
// blocks access to the entire DataSource
139

140     public Connection JavaDoc getConnection() throws SQLException JavaDoc
141     {
142         ensureDriverLoaded();
143
144         waitNoFreezeFile();
145
146         Connection JavaDoc out = driver().connect( jdbcUrl, properties );
147         if (out == null)
148             throw new SQLException JavaDoc("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " +
149                             "driver [" + driver() + "].");
150         return out;
151     }
152
153     // should NOT be sync'ed -- driver() is sync'ed and that's enough
154
// sync'ing the method creates the danger that one freeze on connect
155
// blocks access to the entire DataSource
156

157     public Connection JavaDoc getConnection(String JavaDoc username, String JavaDoc password) throws SQLException JavaDoc
158     {
159         ensureDriverLoaded();
160         
161         waitNoFreezeFile();
162
163         Connection JavaDoc out = driver().connect( jdbcUrl, overrideProps(username, password) );
164         if (out == null)
165             throw new SQLException JavaDoc("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " +
166                             "driver [" + driver() + "].");
167         return out;
168     }
169
170     public PrintWriter JavaDoc getLogWriter() throws SQLException JavaDoc
171     { return DriverManager.getLogWriter(); }
172
173     public void setLogWriter(PrintWriter JavaDoc out) throws SQLException JavaDoc
174     { DriverManager.setLogWriter( out ); }
175
176     public int getLoginTimeout() throws SQLException JavaDoc
177     { return DriverManager.getLoginTimeout(); }
178
179     public void setLoginTimeout(int seconds) throws SQLException JavaDoc
180     { DriverManager.setLoginTimeout( seconds ); }
181
182     //overrides
183
public synchronized void setJdbcUrl(String JavaDoc jdbcUrl)
184     {
185         //System.err.println( "setJdbcUrl( " + jdbcUrl + " )");
186
//new Exception("DEBUG STACK TRACE").printStackTrace();
187
super.setJdbcUrl( jdbcUrl );
188         clearDriver();
189     }
190
191     //"virtual properties"
192
public synchronized void setUser(String JavaDoc user)
193     {
194         String JavaDoc oldUser = this.getUser();
195         if (! eqOrBothNull( user, oldUser ))
196         {
197             if (user != null)
198                 properties.put( SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user );
199             else
200                 properties.remove( SqlUtils.DRIVER_MANAGER_USER_PROPERTY );
201
202             pcs.firePropertyChange("user", oldUser, user);
203         }
204     }
205
206     public synchronized String JavaDoc getUser()
207     {
208 // System.err.println("getUser() -- DriverManagerDataSource@" + System.identityHashCode( this ) +
209
// " using Properties@" + System.identityHashCode( properties ));
210
// new Exception("STACK TRACE DUMP").printStackTrace();
211
return properties.getProperty( SqlUtils.DRIVER_MANAGER_USER_PROPERTY );
212     }
213
214     public synchronized void setPassword(String JavaDoc password)
215     {
216         String JavaDoc oldPass = this.getPassword();
217         if (! eqOrBothNull( password, oldPass ))
218         {
219             if (password != null)
220                 properties.put( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password );
221             else
222                 properties.remove( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY );
223
224             pcs.firePropertyChange("password", oldPass, password);
225         }
226     }
227
228     public synchronized String JavaDoc getPassword()
229     { return properties.getProperty( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); }
230
231     private final Properties JavaDoc overrideProps(String JavaDoc user, String JavaDoc password)
232     {
233         Properties JavaDoc overriding = (Properties JavaDoc) properties.clone(); //we are relying on a defensive clone in our base class!!!
234

235         if (user != null)
236             overriding.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user);
237         else
238             overriding.remove(SqlUtils.DRIVER_MANAGER_USER_PROPERTY);
239
240         if (password != null)
241             overriding.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password);
242         else
243             overriding.remove(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY);
244
245         return overriding;
246     }
247
248     private synchronized Driver JavaDoc driver() throws SQLException JavaDoc
249     {
250         //System.err.println( "driver() <-- " + this );
251
if (driver == null)
252             driver = DriverManager.getDriver( jdbcUrl );
253         return driver;
254     }
255
256     private synchronized void clearDriver()
257     { driver = null; }
258
259     private static boolean eqOrBothNull( Object JavaDoc a, Object JavaDoc b )
260     { return (a == b || (a != null && a.equals(b))); }
261
262     // serialization stuff -- set up bound/constrained property event handlers on deserialization
263
private static final long serialVersionUID = 1;
264     private static final short VERSION = 0x0001;
265
266     private void writeObject( ObjectOutputStream JavaDoc oos ) throws IOException JavaDoc
267     {
268         oos.writeShort( VERSION );
269     }
270
271     private void readObject( ObjectInputStream JavaDoc ois ) throws IOException JavaDoc, ClassNotFoundException JavaDoc
272     {
273         short version = ois.readShort();
274         switch (version)
275         {
276         case VERSION:
277             setUpPropertyListeners();
278             break;
279         default:
280             throw new IOException JavaDoc("Unsupported Serialized Version: " + version);
281         }
282     }
283 }
284
Popular Tags