Source Code Cross Referenced for InstanceKeyDataSource.java in  » Database-JDBC-Connection-Pool » Connection-Pool-DBCP » org » apache » commons » dbcp » datasources » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » Connection Pool DBCP » org.apache.commons.dbcp.datasources 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package org.apache.commons.dbcp.datasources;
019:
020:        import java.io.Serializable;
021:        import java.io.PrintWriter;
022:        import java.sql.Connection;
023:        import java.sql.SQLException;
024:        import java.util.NoSuchElementException;
025:        import java.util.Properties;
026:
027:        import javax.naming.Context;
028:        import javax.naming.InitialContext;
029:        import javax.naming.NamingException;
030:        import javax.naming.Reference;
031:        import javax.naming.StringRefAddr;
032:        import javax.naming.Referenceable;
033:        import javax.sql.ConnectionPoolDataSource;
034:        import javax.sql.DataSource;
035:        import javax.sql.PooledConnection;
036:
037:        import org.apache.commons.dbcp.SQLNestedException;
038:        import org.apache.commons.pool.impl.GenericObjectPool;
039:
040:        /**
041:         * <p>The base class for <code>SharedPoolDataSource</code> and 
042:         * <code>PerUserPoolDataSource</code>.  Many of the configuration properties
043:         * are shared and defined here.  This class is declared public in order
044:         * to allow particular usage with commons-beanutils; do not make direct
045:         * use of it outside of commons-dbcp.
046:         * </p>
047:         *
048:         * <p>
049:         * A J2EE container will normally provide some method of initializing the
050:         * <code>DataSource</code> whose attributes are presented
051:         * as bean getters/setters and then deploying it via JNDI.  It is then
052:         * available to an application as a source of pooled logical connections to 
053:         * the database.  The pool needs a source of physical connections.  This
054:         * source is in the form of a <code>ConnectionPoolDataSource</code> that
055:         * can be specified via the {@link #setDataSourceName(String)} used to
056:         * lookup the source via JNDI.
057:         * </p>
058:         *
059:         * <p>
060:         * Although normally used within a JNDI environment, A DataSource
061:         * can be instantiated and initialized as any bean.  In this case the 
062:         * <code>ConnectionPoolDataSource</code> will likely be instantiated in
063:         * a similar manner.  This class allows the physical source of connections
064:         * to be attached directly to this pool using the 
065:         * {@link #setConnectionPoolDataSource(ConnectionPoolDataSource)} method.
066:         * </p>
067:         *
068:         * <p>
069:         * The dbcp package contains an adapter, 
070:         * {@link org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS},
071:         * that can be used to allow the use of <code>DataSource</code>'s based on this
072:         * class with jdbc driver implementations that do not supply a 
073:         * <code>ConnectionPoolDataSource</code>, but still
074:         * provide a {@link java.sql.Driver} implementation.
075:         * </p>
076:         *
077:         * <p>
078:         * The <a href="package-summary.html">package documentation</a> contains an 
079:         * example using catalina and JNDI and it also contains a non-JNDI example. 
080:         * </p>
081:         *
082:         * @author John D. McNally
083:         * @version $Revision: 500687 $ $Date: 2007-01-27 16:33:47 -0700 (Sat, 27 Jan 2007) $
084:         */
085:        public abstract class InstanceKeyDataSource implements  DataSource,
086:                Referenceable, Serializable {
087:            private static final String GET_CONNECTION_CALLED = "A Connection was already requested from this source, "
088:                    + "further initialization is not allowed.";
089:            private static final String BAD_TRANSACTION_ISOLATION = "The requested TransactionIsolation level is invalid.";
090:            /**
091:             * Internal constant to indicate the level is not set. 
092:             */
093:            protected static final int UNKNOWN_TRANSACTIONISOLATION = -1;
094:
095:            private boolean getConnectionCalled = false;
096:
097:            private ConnectionPoolDataSource cpds = null;
098:            /** DataSource Name used to find the ConnectionPoolDataSource */
099:            private String dataSourceName = null;
100:            private boolean defaultAutoCommit = false;
101:            private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
102:            private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
103:            private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
104:            private int maxWait = (int) Math.min((long) Integer.MAX_VALUE,
105:                    GenericObjectPool.DEFAULT_MAX_WAIT);
106:            private boolean defaultReadOnly = false;
107:            /** Description */
108:            private String description = null;
109:            /** Environment that may be used to set up a jndi initial context. */
110:            Properties jndiEnvironment = null;
111:            /** Login TimeOut in seconds */
112:            private int loginTimeout = 0;
113:            /** Log stream */
114:            private PrintWriter logWriter = null;
115:            private boolean _testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;
116:            private boolean _testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;
117:            private int _timeBetweenEvictionRunsMillis = (int) Math
118:                    .min(
119:                            (long) Integer.MAX_VALUE,
120:                            GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS);
121:            private int _numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
122:            private int _minEvictableIdleTimeMillis = (int) Math.min(
123:                    (long) Integer.MAX_VALUE,
124:                    GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
125:            private boolean _testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;
126:            private String validationQuery = null;
127:            private boolean rollbackAfterValidation = false;
128:            private boolean testPositionSet = false;
129:
130:            protected String instanceKey = null;
131:
132:            /**
133:             * Default no-arg constructor for Serialization
134:             */
135:            public InstanceKeyDataSource() {
136:                defaultAutoCommit = true;
137:            }
138:
139:            /**
140:             * Throws an IllegalStateException, if a PooledConnection has already
141:             * been requested.
142:             */
143:            protected void assertInitializationAllowed()
144:                    throws IllegalStateException {
145:                if (getConnectionCalled) {
146:                    throw new IllegalStateException(GET_CONNECTION_CALLED);
147:                }
148:            }
149:
150:            /**
151:             * Close pool being maintained by this datasource.
152:             */
153:            public abstract void close() throws Exception;
154:
155:            // -------------------------------------------------------------------
156:            // Properties
157:
158:            /**
159:             * Get the value of connectionPoolDataSource.  This method will return
160:             * null, if the backing datasource is being accessed via jndi.
161:             *
162:             * @return value of connectionPoolDataSource.
163:             */
164:            public ConnectionPoolDataSource getConnectionPoolDataSource() {
165:                return cpds;
166:            }
167:
168:            /**
169:             * Set the backend ConnectionPoolDataSource.  This property should not be
170:             * set if using jndi to access the datasource.
171:             *
172:             * @param v  Value to assign to connectionPoolDataSource.
173:             */
174:            public void setConnectionPoolDataSource(ConnectionPoolDataSource v) {
175:                assertInitializationAllowed();
176:                if (dataSourceName != null) {
177:                    throw new IllegalStateException(
178:                            "Cannot set the DataSource, if JNDI is used.");
179:                }
180:                if (cpds != null) {
181:                    throw new IllegalStateException(
182:                            "The CPDS has already been set. It cannot be altered.");
183:                }
184:                cpds = v;
185:                instanceKey = InstanceKeyObjectFactory
186:                        .registerNewInstance(this );
187:            }
188:
189:            /**
190:             * Get the name of the ConnectionPoolDataSource which backs this pool.
191:             * This name is used to look up the datasource from a jndi service 
192:             * provider.
193:             *
194:             * @return value of dataSourceName.
195:             */
196:            public String getDataSourceName() {
197:                return dataSourceName;
198:            }
199:
200:            /**
201:             * Set the name of the ConnectionPoolDataSource which backs this pool.
202:             * This name is used to look up the datasource from a jndi service 
203:             * provider.
204:             *
205:             * @param v  Value to assign to dataSourceName.
206:             */
207:            public void setDataSourceName(String v) {
208:                assertInitializationAllowed();
209:                if (cpds != null) {
210:                    throw new IllegalStateException(
211:                            "Cannot set the JNDI name for the DataSource, if already "
212:                                    + "set using setConnectionPoolDataSource.");
213:                }
214:                if (dataSourceName != null) {
215:                    throw new IllegalStateException(
216:                            "The DataSourceName has already been set. "
217:                                    + "It cannot be altered.");
218:                }
219:                this .dataSourceName = v;
220:                instanceKey = InstanceKeyObjectFactory
221:                        .registerNewInstance(this );
222:            }
223:
224:            /** 
225:             * Get the value of defaultAutoCommit, which defines the state of 
226:             * connections handed out from this pool.  The value can be changed
227:             * on the Connection using Connection.setAutoCommit(boolean).
228:             * The default is true.
229:             *
230:             * @return value of defaultAutoCommit.
231:             */
232:            public boolean isDefaultAutoCommit() {
233:                return defaultAutoCommit;
234:            }
235:
236:            /**
237:             * Set the value of defaultAutoCommit, which defines the state of 
238:             * connections handed out from this pool.  The value can be changed
239:             * on the Connection using Connection.setAutoCommit(boolean).
240:             * The default is true.
241:             *
242:             * @param v  Value to assign to defaultAutoCommit.
243:             */
244:            public void setDefaultAutoCommit(boolean v) {
245:                assertInitializationAllowed();
246:                this .defaultAutoCommit = v;
247:            }
248:
249:            /**
250:             * Get the value of defaultReadOnly, which defines the state of 
251:             * connections handed out from this pool.  The value can be changed
252:             * on the Connection using Connection.setReadOnly(boolean).
253:             * The default is false.
254:             *
255:             * @return value of defaultReadOnly.
256:             */
257:            public boolean isDefaultReadOnly() {
258:                return defaultReadOnly;
259:            }
260:
261:            /**
262:             * Set the value of defaultReadOnly, which defines the state of 
263:             * connections handed out from this pool.  The value can be changed
264:             * on the Connection using Connection.setReadOnly(boolean).
265:             * The default is false.
266:             *
267:             * @param v  Value to assign to defaultReadOnly.
268:             */
269:            public void setDefaultReadOnly(boolean v) {
270:                assertInitializationAllowed();
271:                this .defaultReadOnly = v;
272:            }
273:
274:            /**
275:             * Get the value of defaultTransactionIsolation, which defines the state of
276:             * connections handed out from this pool.  The value can be changed
277:             * on the Connection using Connection.setTransactionIsolation(int).
278:             * If this method returns -1, the default is JDBC driver dependent.
279:             * 
280:             * @return value of defaultTransactionIsolation.
281:             */
282:            public int getDefaultTransactionIsolation() {
283:                return defaultTransactionIsolation;
284:            }
285:
286:            /**
287:             * Set the value of defaultTransactionIsolation, which defines the state of
288:             * connections handed out from this pool.  The value can be changed
289:             * on the Connection using Connection.setTransactionIsolation(int).
290:             * The default is JDBC driver dependent.
291:             * 
292:             * @param v  Value to assign to defaultTransactionIsolation
293:             */
294:            public void setDefaultTransactionIsolation(int v) {
295:                assertInitializationAllowed();
296:                switch (v) {
297:                case Connection.TRANSACTION_NONE:
298:                case Connection.TRANSACTION_READ_COMMITTED:
299:                case Connection.TRANSACTION_READ_UNCOMMITTED:
300:                case Connection.TRANSACTION_REPEATABLE_READ:
301:                case Connection.TRANSACTION_SERIALIZABLE:
302:                    break;
303:                default:
304:                    throw new IllegalArgumentException(
305:                            BAD_TRANSACTION_ISOLATION);
306:                }
307:                this .defaultTransactionIsolation = v;
308:            }
309:
310:            /**
311:             * Get the description.  This property is defined by jdbc as for use with
312:             * GUI (or other) tools that might deploy the datasource.  It serves no
313:             * internal purpose.
314:             *
315:             * @return value of description.
316:             */
317:            public String getDescription() {
318:                return description;
319:            }
320:
321:            /**
322:             * Set the description.  This property is defined by jdbc as for use with
323:             * GUI (or other) tools that might deploy the datasource.  It serves no
324:             * internal purpose.
325:             * 
326:             * @param v  Value to assign to description.
327:             */
328:            public void setDescription(String v) {
329:                this .description = v;
330:            }
331:
332:            /**
333:             * Get the value of jndiEnvironment which is used when instantiating
334:             * a jndi InitialContext.  This InitialContext is used to locate the
335:             * backend ConnectionPoolDataSource.
336:             *
337:             * @return value of jndiEnvironment.
338:             */
339:            public String getJndiEnvironment(String key) {
340:                String value = null;
341:                if (jndiEnvironment != null) {
342:                    value = jndiEnvironment.getProperty(key);
343:                }
344:                return value;
345:            }
346:
347:            /**
348:             * Sets the value of the given JNDI environment property to be used when
349:             * instantiating a JNDI InitialContext. This InitialContext is used to
350:             * locate the backend ConnectionPoolDataSource.
351:             * 
352:             * @param key the JNDI environment property to set.
353:             * @param value the value assigned to specified JNDI environment property.
354:             */
355:            public void setJndiEnvironment(String key, String value) {
356:                if (jndiEnvironment == null) {
357:                    jndiEnvironment = new Properties();
358:                }
359:                jndiEnvironment.setProperty(key, value);
360:            }
361:
362:            /**
363:             * Get the value of loginTimeout.
364:             * @return value of loginTimeout.
365:             */
366:            public int getLoginTimeout() {
367:                return loginTimeout;
368:            }
369:
370:            /**
371:             * Set the value of loginTimeout.
372:             * @param v  Value to assign to loginTimeout.
373:             */
374:            public void setLoginTimeout(int v) {
375:                this .loginTimeout = v;
376:            }
377:
378:            /**
379:             * Get the value of logWriter.
380:             * @return value of logWriter.
381:             */
382:            public PrintWriter getLogWriter() {
383:                if (logWriter == null) {
384:                    logWriter = new PrintWriter(System.out);
385:                }
386:                return logWriter;
387:            }
388:
389:            /**
390:             * Set the value of logWriter.
391:             * @param v  Value to assign to logWriter.
392:             */
393:            public void setLogWriter(PrintWriter v) {
394:                this .logWriter = v;
395:            }
396:
397:            /**
398:             * @see #getTestOnBorrow
399:             */
400:            public final boolean isTestOnBorrow() {
401:                return getTestOnBorrow();
402:            }
403:
404:            /**
405:             * When <tt>true</tt>, objects will be
406:             * {*link PoolableObjectFactory#validateObject validated}
407:             * before being returned by the {*link #borrowObject}
408:             * method.  If the object fails to validate,
409:             * it will be dropped from the pool, and we will attempt
410:             * to borrow another.
411:             *
412:             * @see #setTestOnBorrow
413:             */
414:            public boolean getTestOnBorrow() {
415:                return _testOnBorrow;
416:            }
417:
418:            /**
419:             * When <tt>true</tt>, objects will be
420:             * {*link PoolableObjectFactory#validateObject validated}
421:             * before being returned by the {*link #borrowObject}
422:             * method.  If the object fails to validate,
423:             * it will be dropped from the pool, and we will attempt
424:             * to borrow another. For a <code>true</code> value to have any effect,
425:             * the <code>validationQuery</code> property must be set to a non-null
426:             * string.
427:             *
428:             * @see #getTestOnBorrow
429:             */
430:            public void setTestOnBorrow(boolean testOnBorrow) {
431:                assertInitializationAllowed();
432:                _testOnBorrow = testOnBorrow;
433:                testPositionSet = true;
434:            }
435:
436:            /**
437:             * @see #getTestOnReturn
438:             */
439:            public final boolean isTestOnReturn() {
440:                return getTestOnReturn();
441:            }
442:
443:            /**
444:             * When <tt>true</tt>, objects will be
445:             * {*link PoolableObjectFactory#validateObject validated}
446:             * before being returned to the pool within the
447:             * {*link #returnObject}.
448:             *
449:             * @see #setTestOnReturn
450:             */
451:            public boolean getTestOnReturn() {
452:                return _testOnReturn;
453:            }
454:
455:            /**
456:             * When <tt>true</tt>, objects will be
457:             * {*link PoolableObjectFactory#validateObject validated}
458:             * before being returned to the pool within the
459:             * {*link #returnObject}. For a <code>true</code> value to have any effect,
460:             * the <code>validationQuery</code> property must be set to a non-null
461:             * string.
462:             *
463:             * @see #getTestOnReturn
464:             */
465:            public void setTestOnReturn(boolean testOnReturn) {
466:                assertInitializationAllowed();
467:                _testOnReturn = testOnReturn;
468:                testPositionSet = true;
469:            }
470:
471:            /**
472:             * Returns the number of milliseconds to sleep between runs of the
473:             * idle object evictor thread.
474:             * When non-positive, no idle object evictor thread will be
475:             * run.
476:             *
477:             * @see #setTimeBetweenEvictionRunsMillis
478:             */
479:            public int getTimeBetweenEvictionRunsMillis() {
480:                return _timeBetweenEvictionRunsMillis;
481:            }
482:
483:            /**
484:             * Sets the number of milliseconds to sleep between runs of the
485:             * idle object evictor thread.
486:             * When non-positive, no idle object evictor thread will be
487:             * run.
488:             *
489:             * @see #getTimeBetweenEvictionRunsMillis
490:             */
491:            public void setTimeBetweenEvictionRunsMillis(
492:                    int timeBetweenEvictionRunsMillis) {
493:                assertInitializationAllowed();
494:                _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
495:            }
496:
497:            /**
498:             * Returns the number of objects to examine during each run of the
499:             * idle object evictor thread (if any).
500:             *
501:             * @see #setNumTestsPerEvictionRun
502:             * @see #setTimeBetweenEvictionRunsMillis
503:             */
504:            public int getNumTestsPerEvictionRun() {
505:                return _numTestsPerEvictionRun;
506:            }
507:
508:            /**
509:             * Sets the number of objects to examine during each run of the
510:             * idle object evictor thread (if any).
511:             * <p>
512:             * When a negative value is supplied, <tt>ceil({*link #numIdle})/abs({*link #getNumTestsPerEvictionRun})</tt>
513:             * tests will be run.  I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
514:             * idle objects will be tested per run.
515:             *
516:             * @see #getNumTestsPerEvictionRun
517:             * @see #setTimeBetweenEvictionRunsMillis
518:             */
519:            public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
520:                assertInitializationAllowed();
521:                _numTestsPerEvictionRun = numTestsPerEvictionRun;
522:            }
523:
524:            /**
525:             * Returns the minimum amount of time an object may sit idle in the pool
526:             * before it is eligable for eviction by the idle object evictor
527:             * (if any).
528:             *
529:             * @see #setMinEvictableIdleTimeMillis
530:             * @see #setTimeBetweenEvictionRunsMillis
531:             */
532:            public int getMinEvictableIdleTimeMillis() {
533:                return _minEvictableIdleTimeMillis;
534:            }
535:
536:            /**
537:             * Sets the minimum amount of time an object may sit idle in the pool
538:             * before it is eligable for eviction by the idle object evictor
539:             * (if any).
540:             * When non-positive, no objects will be evicted from the pool
541:             * due to idle time alone.
542:             *
543:             * @see #getMinEvictableIdleTimeMillis
544:             * @see #setTimeBetweenEvictionRunsMillis
545:             */
546:            public void setMinEvictableIdleTimeMillis(
547:                    int minEvictableIdleTimeMillis) {
548:                assertInitializationAllowed();
549:                _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
550:            }
551:
552:            /**
553:             * @see #getTestWhileIdle
554:             */
555:            public final boolean isTestWhileIdle() {
556:                return getTestWhileIdle();
557:            }
558:
559:            /**
560:             * When <tt>true</tt>, objects will be
561:             * {*link PoolableObjectFactory#validateObject validated}
562:             * by the idle object evictor (if any).  If an object
563:             * fails to validate, it will be dropped from the pool.
564:             *
565:             * @see #setTestWhileIdle
566:             * @see #setTimeBetweenEvictionRunsMillis
567:             */
568:            public boolean getTestWhileIdle() {
569:                return _testWhileIdle;
570:            }
571:
572:            /**
573:             * When <tt>true</tt>, objects will be
574:             * {*link PoolableObjectFactory#validateObject validated}
575:             * by the idle object evictor (if any).  If an object
576:             * fails to validate, it will be dropped from the pool. For a
577:             * <code>true</code> value to have any effect,
578:             * the <code>validationQuery</code> property must be set to a non-null
579:             * string.
580:             *
581:             * @see #getTestWhileIdle
582:             * @see #setTimeBetweenEvictionRunsMillis
583:             */
584:            public void setTestWhileIdle(boolean testWhileIdle) {
585:                assertInitializationAllowed();
586:                _testWhileIdle = testWhileIdle;
587:                testPositionSet = true;
588:            }
589:
590:            /**
591:             * The SQL query that will be used to validate connections from this pool
592:             * before returning them to the caller.  If specified, this query
593:             * <strong>MUST</strong> be an SQL SELECT statement that returns at least
594:             * one row.
595:             */
596:            public String getValidationQuery() {
597:                return (this .validationQuery);
598:            }
599:
600:            /**
601:             * The SQL query that will be used to validate connections from this pool
602:             * before returning them to the caller.  If specified, this query
603:             * <strong>MUST</strong> be an SQL SELECT statement that returns at least
604:             * one row.  Default behavior is to test the connection when it is
605:             * borrowed.
606:             */
607:            public void setValidationQuery(String validationQuery) {
608:                assertInitializationAllowed();
609:                this .validationQuery = validationQuery;
610:                if (!testPositionSet) {
611:                    setTestOnBorrow(true);
612:                }
613:            }
614:
615:            /**
616:             * Whether a rollback will be issued after executing the SQL query 
617:             * that will be used to validate connections from this pool
618:             * before returning them to the caller.
619:             * 
620:             * @return true if a rollback will be issued after executing the
621:             * validation query
622:             * @since 1.2.2
623:             */
624:            public boolean isRollbackAfterValidation() {
625:                return (this .rollbackAfterValidation);
626:            }
627:
628:            /**
629:             * Whether a rollback will be issued after executing the SQL query 
630:             * that will be used to validate connections from this pool
631:             * before returning them to the caller. Default behavior is NOT
632:             * to issue a rollback. The setting will only have an effect
633:             * if a validation query is set
634:             * 
635:             * @param rollbackAfterValidation new property value
636:             * @since 1.2.2
637:             */
638:            public void setRollbackAfterValidation(
639:                    boolean rollbackAfterValidation) {
640:                assertInitializationAllowed();
641:                this .rollbackAfterValidation = rollbackAfterValidation;
642:            }
643:
644:            // ----------------------------------------------------------------------
645:            // Instrumentation Methods
646:
647:            // ----------------------------------------------------------------------
648:            // DataSource implementation 
649:
650:            /**
651:             * Attempt to establish a database connection.
652:             */
653:            public Connection getConnection() throws SQLException {
654:                return getConnection(null, null);
655:            }
656:
657:            /**
658:             * Attempt to establish a database connection.
659:             */
660:            public Connection getConnection(String username, String password)
661:                    throws SQLException {
662:                if (instanceKey == null) {
663:                    throw new SQLException(
664:                            "Must set the ConnectionPoolDataSource "
665:                                    + "through setDataSourceName or setConnectionPoolDataSource"
666:                                    + " before calling getConnection.");
667:                }
668:                getConnectionCalled = true;
669:                PooledConnectionAndInfo info = null;
670:                try {
671:                    info = getPooledConnectionAndInfo(username, password);
672:                } catch (NoSuchElementException e) {
673:                    closeDueToException(info);
674:                    throw new SQLNestedException(
675:                            "Cannot borrow connection from pool", e);
676:                } catch (RuntimeException e) {
677:                    closeDueToException(info);
678:                    throw e;
679:                } catch (SQLException e) {
680:                    closeDueToException(info);
681:                    throw e;
682:                } catch (Exception e) {
683:                    closeDueToException(info);
684:                    throw new SQLNestedException(
685:                            "Cannot borrow connection from pool", e);
686:                }
687:
688:                if (!(null == password ? null == info.getPassword() : password
689:                        .equals(info.getPassword()))) {
690:                    closeDueToException(info);
691:                    throw new SQLException(
692:                            "Given password did not match password used"
693:                                    + " to create the PooledConnection.");
694:                }
695:
696:                Connection con = info.getPooledConnection().getConnection();
697:                setupDefaults(con, username);
698:                con.clearWarnings();
699:                return con;
700:            }
701:
702:            protected abstract PooledConnectionAndInfo getPooledConnectionAndInfo(
703:                    String username, String password) throws SQLException;
704:
705:            protected abstract void setupDefaults(Connection con,
706:                    String username) throws SQLException;
707:
708:            private void closeDueToException(PooledConnectionAndInfo info) {
709:                if (info != null) {
710:                    try {
711:                        info.getPooledConnection().getConnection().close();
712:                    } catch (Exception e) {
713:                        // do not throw this exception because we are in the middle
714:                        // of handling another exception.  But record it because
715:                        // it potentially leaks connections from the pool.
716:                        getLogWriter().println(
717:                                "[ERROR] Could not return connection to "
718:                                        + "pool during exception handling. "
719:                                        + e.getMessage());
720:                    }
721:                }
722:            }
723:
724:            protected ConnectionPoolDataSource testCPDS(String username,
725:                    String password) throws javax.naming.NamingException,
726:                    SQLException {
727:                // The source of physical db connections
728:                ConnectionPoolDataSource cpds = this .cpds;
729:                if (cpds == null) {
730:                    Context ctx = null;
731:                    if (jndiEnvironment == null) {
732:                        ctx = new InitialContext();
733:                    } else {
734:                        ctx = new InitialContext(jndiEnvironment);
735:                    }
736:                    Object ds = ctx.lookup(dataSourceName);
737:                    if (ds instanceof  ConnectionPoolDataSource) {
738:                        cpds = (ConnectionPoolDataSource) ds;
739:                    } else {
740:                        throw new SQLException(
741:                                "Illegal configuration: "
742:                                        + "DataSource "
743:                                        + dataSourceName
744:                                        + " ("
745:                                        + ds.getClass().getName()
746:                                        + ")"
747:                                        + " doesn't implement javax.sql.ConnectionPoolDataSource");
748:                    }
749:                }
750:
751:                // try to get a connection with the supplied username/password
752:                PooledConnection conn = null;
753:                try {
754:                    if (username != null) {
755:                        conn = cpds.getPooledConnection(username, password);
756:                    } else {
757:                        conn = cpds.getPooledConnection();
758:                    }
759:                    if (conn == null) {
760:                        throw new SQLException(
761:                                "Cannot connect using the supplied username/password");
762:                    }
763:                } finally {
764:                    if (conn != null) {
765:                        try {
766:                            conn.close();
767:                        } catch (SQLException e) {
768:                            // at least we could connect
769:                        }
770:                    }
771:                }
772:                return cpds;
773:            }
774:
775:            protected byte whenExhaustedAction(int maxActive, int maxWait) {
776:                byte whenExhausted = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
777:                if (maxActive <= 0) {
778:                    whenExhausted = GenericObjectPool.WHEN_EXHAUSTED_GROW;
779:                } else if (maxWait == 0) {
780:                    whenExhausted = GenericObjectPool.WHEN_EXHAUSTED_FAIL;
781:                }
782:                return whenExhausted;
783:            }
784:
785:            // ----------------------------------------------------------------------
786:            // Referenceable implementation 
787:
788:            /**
789:             * Retrieves the Reference of this object.
790:             * <strong>Note:</strong> <code>InstanceKeyDataSource</code> subclasses
791:             * should override this method. The implementaion included below
792:             * is not robust and will be removed at the next major version DBCP
793:             * release.
794:             *
795:             * @return The non-null Reference of this object.
796:             * @exception NamingException If a naming exception was encountered
797:             *      while retrieving the reference.
798:             */
799:            // TODO: Remove the implementation of this method at next major
800:            // version release.
801:            public Reference getReference() throws NamingException {
802:                final String className = getClass().getName();
803:                final String factoryName = className + "Factory"; // XXX: not robust 
804:                Reference ref = new Reference(className, factoryName, null);
805:                ref.add(new StringRefAddr("instanceKey", instanceKey));
806:                return ref;
807:            }
808:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.