Source Code Cross Referenced for SimpleDataSource.java in  » Database-ORM » iBATIS » com » ibatis » common » jdbc » 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 ORM » iBATIS » com.ibatis.common.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Copyright 2004 Clinton Begin
0003:         *
0004:         *  Licensed under the Apache License, Version 2.0 (the "License");
0005:         *  you may not use this file except in compliance with the License.
0006:         *  You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         *  Unless required by applicable law or agreed to in writing, software
0011:         *  distributed under the License is distributed on an "AS IS" BASIS,
0012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         *  See the License for the specific language governing permissions and
0014:         *  limitations under the License.
0015:         */
0016:        package com.ibatis.common.jdbc;
0017:
0018:        import com.ibatis.common.beans.ClassInfo;
0019:
0020:        import com.ibatis.common.resources.Resources;
0021:        import com.ibatis.common.logging.LogFactory;
0022:        import com.ibatis.common.logging.Log;
0023:
0024:        import javax.sql.DataSource;
0025:        import java.io.PrintWriter;
0026:        import java.lang.reflect.InvocationHandler;
0027:        import java.lang.reflect.Method;
0028:        import java.lang.reflect.Proxy;
0029:        import java.sql.*;
0030:        import java.util.*;
0031:
0032:        /**
0033:         * This is a simple, synchronous, thread-safe database connection pool.
0034:         * <p/>
0035:         * REQUIRED PROPERTIES
0036:         * -------------------
0037:         * JDBC.Driver
0038:         * JDBC.ConnectionURL
0039:         * JDBC.Username
0040:         * JDBC.Password
0041:         * <p/>
0042:         * Pool.MaximumActiveConnections
0043:         * Pool.MaximumIdleConnections
0044:         * Pool.MaximumCheckoutTime
0045:         * Pool.TimeToWait
0046:         * Pool.PingQuery
0047:         * Pool.PingEnabled
0048:         * Pool.PingConnectionsOlderThan
0049:         * Pool.PingConnectionsNotUsedFor
0050:         * Pool.QuietMode
0051:         */
0052:        public class SimpleDataSource implements  DataSource {
0053:
0054:            private static final Log log = LogFactory
0055:                    .getLog(SimpleDataSource.class);
0056:
0057:            // Required Properties
0058:            private static final String PROP_JDBC_DRIVER = "JDBC.Driver";
0059:            private static final String PROP_JDBC_URL = "JDBC.ConnectionURL";
0060:            private static final String PROP_JDBC_USERNAME = "JDBC.Username";
0061:            private static final String PROP_JDBC_PASSWORD = "JDBC.Password";
0062:            private static final String PROP_JDBC_DEFAULT_AUTOCOMMIT = "JDBC.DefaultAutoCommit";
0063:
0064:            // Optional Properties
0065:            private static final String PROP_POOL_MAX_ACTIVE_CONN = "Pool.MaximumActiveConnections";
0066:            private static final String PROP_POOL_MAX_IDLE_CONN = "Pool.MaximumIdleConnections";
0067:            private static final String PROP_POOL_MAX_CHECKOUT_TIME = "Pool.MaximumCheckoutTime";
0068:            private static final String PROP_POOL_TIME_TO_WAIT = "Pool.TimeToWait";
0069:            private static final String PROP_POOL_PING_QUERY = "Pool.PingQuery";
0070:            private static final String PROP_POOL_PING_CONN_OLDER_THAN = "Pool.PingConnectionsOlderThan";
0071:            private static final String PROP_POOL_PING_ENABLED = "Pool.PingEnabled";
0072:            private static final String PROP_POOL_PING_CONN_NOT_USED_FOR = "Pool.PingConnectionsNotUsedFor";
0073:            private int expectedConnectionTypeCode;
0074:            // Additional Driver Properties prefix
0075:            private static final String ADD_DRIVER_PROPS_PREFIX = "Driver.";
0076:            private static final int ADD_DRIVER_PROPS_PREFIX_LENGTH = ADD_DRIVER_PROPS_PREFIX
0077:                    .length();
0078:
0079:            // ----- BEGIN: FIELDS LOCKED BY POOL_LOCK -----
0080:            private final Object POOL_LOCK = new Object();
0081:            private List idleConnections = new ArrayList();
0082:            private List activeConnections = new ArrayList();
0083:            private long requestCount = 0;
0084:            private long accumulatedRequestTime = 0;
0085:            private long accumulatedCheckoutTime = 0;
0086:            private long claimedOverdueConnectionCount = 0;
0087:            private long accumulatedCheckoutTimeOfOverdueConnections = 0;
0088:            private long accumulatedWaitTime = 0;
0089:            private long hadToWaitCount = 0;
0090:            private long badConnectionCount = 0;
0091:            // ----- END: FIELDS LOCKED BY POOL_LOCK -----
0092:
0093:            // ----- BEGIN: PROPERTY FIELDS FOR CONFIGURATION -----
0094:            private String jdbcDriver;
0095:            private String jdbcUrl;
0096:            private String jdbcUsername;
0097:            private String jdbcPassword;
0098:            private boolean jdbcDefaultAutoCommit;
0099:            private Properties driverProps;
0100:            private boolean useDriverProps;
0101:
0102:            private int poolMaximumActiveConnections;
0103:            private int poolMaximumIdleConnections;
0104:            private int poolMaximumCheckoutTime;
0105:            private int poolTimeToWait;
0106:            private String poolPingQuery;
0107:            private boolean poolPingEnabled;
0108:            private int poolPingConnectionsOlderThan;
0109:            private int poolPingConnectionsNotUsedFor;
0110:
0111:            //----- END: PROPERTY FIELDS FOR CONFIGURATION -----
0112:
0113:            /**
0114:             * Constructor to allow passing in a map of properties for configuration
0115:             *
0116:             * @param props - the configuration parameters
0117:             */
0118:            public SimpleDataSource(Map props) {
0119:                initialize(props);
0120:            }
0121:
0122:            private void initialize(Map props) {
0123:                try {
0124:                    String prop_pool_ping_query = null;
0125:
0126:                    if (props == null) {
0127:                        throw new RuntimeException(
0128:                                "SimpleDataSource: The properties map passed to the initializer was null.");
0129:                    }
0130:
0131:                    if (!(props.containsKey(PROP_JDBC_DRIVER)
0132:                            && props.containsKey(PROP_JDBC_URL)
0133:                            && props.containsKey(PROP_JDBC_USERNAME) && props
0134:                            .containsKey(PROP_JDBC_PASSWORD))) {
0135:                        throw new RuntimeException(
0136:                                "SimpleDataSource: Some properties were not set.");
0137:                    } else {
0138:
0139:                        jdbcDriver = (String) props.get(PROP_JDBC_DRIVER);
0140:                        jdbcUrl = (String) props.get(PROP_JDBC_URL);
0141:                        jdbcUsername = (String) props.get(PROP_JDBC_USERNAME);
0142:                        jdbcPassword = (String) props.get(PROP_JDBC_PASSWORD);
0143:
0144:                        poolMaximumActiveConnections = props
0145:                                .containsKey(PROP_POOL_MAX_ACTIVE_CONN) ? Integer
0146:                                .parseInt((String) props
0147:                                        .get(PROP_POOL_MAX_ACTIVE_CONN))
0148:                                : 10;
0149:
0150:                        poolMaximumIdleConnections = props
0151:                                .containsKey(PROP_POOL_MAX_IDLE_CONN) ? Integer
0152:                                .parseInt((String) props
0153:                                        .get(PROP_POOL_MAX_IDLE_CONN)) : 5;
0154:
0155:                        poolMaximumCheckoutTime = props
0156:                                .containsKey(PROP_POOL_MAX_CHECKOUT_TIME) ? Integer
0157:                                .parseInt((String) props
0158:                                        .get(PROP_POOL_MAX_CHECKOUT_TIME))
0159:                                : 20000;
0160:
0161:                        poolTimeToWait = props
0162:                                .containsKey(PROP_POOL_TIME_TO_WAIT) ? Integer
0163:                                .parseInt((String) props
0164:                                        .get(PROP_POOL_TIME_TO_WAIT)) : 20000;
0165:
0166:                        poolPingEnabled = props
0167:                                .containsKey(PROP_POOL_PING_ENABLED)
0168:                                && Boolean.valueOf(
0169:                                        (String) props
0170:                                                .get(PROP_POOL_PING_ENABLED))
0171:                                        .booleanValue();
0172:
0173:                        prop_pool_ping_query = (String) props
0174:                                .get(PROP_POOL_PING_QUERY);
0175:                        poolPingQuery = props.containsKey(PROP_POOL_PING_QUERY) ? prop_pool_ping_query
0176:                                : "NO PING QUERY SET";
0177:
0178:                        poolPingConnectionsOlderThan = props
0179:                                .containsKey(PROP_POOL_PING_CONN_OLDER_THAN) ? Integer
0180:                                .parseInt((String) props
0181:                                        .get(PROP_POOL_PING_CONN_OLDER_THAN))
0182:                                : 0;
0183:
0184:                        poolPingConnectionsNotUsedFor = props
0185:                                .containsKey(PROP_POOL_PING_CONN_NOT_USED_FOR) ? Integer
0186:                                .parseInt((String) props
0187:                                        .get(PROP_POOL_PING_CONN_NOT_USED_FOR))
0188:                                : 0;
0189:
0190:                        jdbcDefaultAutoCommit = props
0191:                                .containsKey(PROP_JDBC_DEFAULT_AUTOCOMMIT)
0192:                                && Boolean
0193:                                        .valueOf(
0194:                                                (String) props
0195:                                                        .get(PROP_JDBC_DEFAULT_AUTOCOMMIT))
0196:                                        .booleanValue();
0197:
0198:                        useDriverProps = false;
0199:                        Iterator propIter = props.keySet().iterator();
0200:                        driverProps = new Properties();
0201:                        driverProps.put("user", jdbcUsername);
0202:                        driverProps.put("password", jdbcPassword);
0203:                        while (propIter.hasNext()) {
0204:                            String name = (String) propIter.next();
0205:                            String value = (String) props.get(name);
0206:                            if (name.startsWith(ADD_DRIVER_PROPS_PREFIX)) {
0207:                                driverProps
0208:                                        .put(
0209:                                                name
0210:                                                        .substring(ADD_DRIVER_PROPS_PREFIX_LENGTH),
0211:                                                value);
0212:                                useDriverProps = true;
0213:                            }
0214:                        }
0215:
0216:                        expectedConnectionTypeCode = assembleConnectionTypeCode(
0217:                                jdbcUrl, jdbcUsername, jdbcPassword);
0218:
0219:                        Resources.instantiate(jdbcDriver);
0220:
0221:                        if (poolPingEnabled
0222:                                && (!props.containsKey(PROP_POOL_PING_QUERY) || prop_pool_ping_query
0223:                                        .trim().length() == 0)) {
0224:                            throw new RuntimeException(
0225:                                    "SimpleDataSource: property '"
0226:                                            + PROP_POOL_PING_ENABLED
0227:                                            + "' is true, but property '"
0228:                                            + PROP_POOL_PING_QUERY
0229:                                            + "' is not set correctly.");
0230:                        }
0231:                    }
0232:
0233:                } catch (Exception e) {
0234:                    log.error(
0235:                            "SimpleDataSource: Error while loading properties. Cause: "
0236:                                    + e.toString(), e);
0237:                    throw new RuntimeException(
0238:                            "SimpleDataSource: Error while loading properties. Cause: "
0239:                                    + e, e);
0240:                }
0241:            }
0242:
0243:            private int assembleConnectionTypeCode(String url, String username,
0244:                    String password) {
0245:                return ("" + url + username + password).hashCode();
0246:            }
0247:
0248:            /**
0249:             * @see javax.sql.DataSource#getConnection()
0250:             */
0251:            public Connection getConnection() throws SQLException {
0252:                return popConnection(jdbcUsername, jdbcPassword)
0253:                        .getProxyConnection();
0254:            }
0255:
0256:            /**
0257:             * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
0258:             */
0259:            public Connection getConnection(String username, String password)
0260:                    throws SQLException {
0261:                return popConnection(username, password).getProxyConnection();
0262:            }
0263:
0264:            /**
0265:             * @see javax.sql.DataSource#setLoginTimeout(int)
0266:             */
0267:            public void setLoginTimeout(int loginTimeout) throws SQLException {
0268:                DriverManager.setLoginTimeout(loginTimeout);
0269:            }
0270:
0271:            /**
0272:             * @see javax.sql.DataSource#getLoginTimeout()
0273:             */
0274:            public int getLoginTimeout() throws SQLException {
0275:                return DriverManager.getLoginTimeout();
0276:            }
0277:
0278:            /**
0279:             * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
0280:             */
0281:            public void setLogWriter(PrintWriter logWriter) throws SQLException {
0282:                DriverManager.setLogWriter(logWriter);
0283:            }
0284:
0285:            /**
0286:             * @see javax.sql.DataSource#getLogWriter()
0287:             */
0288:            public PrintWriter getLogWriter() throws SQLException {
0289:                return DriverManager.getLogWriter();
0290:            }
0291:
0292:            /**
0293:             * If a connection has not been used in this many milliseconds, ping the
0294:             * database to make sure the connection is still good.
0295:             *
0296:             * @return the number of milliseconds of inactivity that will trigger a ping
0297:             */
0298:            public int getPoolPingConnectionsNotUsedFor() {
0299:                return poolPingConnectionsNotUsedFor;
0300:            }
0301:
0302:            /**
0303:             * Getter for the name of the JDBC driver class used
0304:             * @return The name of the class
0305:             */
0306:            public String getJdbcDriver() {
0307:                return jdbcDriver;
0308:            }
0309:
0310:            /**
0311:             * Getter of the JDBC URL used
0312:             * @return The JDBC URL
0313:             */
0314:            public String getJdbcUrl() {
0315:                return jdbcUrl;
0316:            }
0317:
0318:            /**
0319:             * Getter for the JDBC user name used
0320:             * @return The user name
0321:             */
0322:            public String getJdbcUsername() {
0323:                return jdbcUsername;
0324:            }
0325:
0326:            /**
0327:             * Getter for the JDBC password used
0328:             * @return The password
0329:             */
0330:            public String getJdbcPassword() {
0331:                return jdbcPassword;
0332:            }
0333:
0334:            /**
0335:             * Getter for the maximum number of active connections
0336:             * @return The maximum number of active connections
0337:             */
0338:            public int getPoolMaximumActiveConnections() {
0339:                return poolMaximumActiveConnections;
0340:            }
0341:
0342:            /**
0343:             * Getter for the maximum number of idle connections
0344:             * @return The maximum number of idle connections
0345:             */
0346:            public int getPoolMaximumIdleConnections() {
0347:                return poolMaximumIdleConnections;
0348:            }
0349:
0350:            /**
0351:             * Getter for the maximum time a connection can be used before it *may* be
0352:             * given away again.
0353:             * @return The maximum time
0354:             */
0355:            public int getPoolMaximumCheckoutTime() {
0356:                return poolMaximumCheckoutTime;
0357:            }
0358:
0359:            /**
0360:             * Getter for the time to wait before retrying to get a connection
0361:             * @return The time to wait
0362:             */
0363:            public int getPoolTimeToWait() {
0364:                return poolTimeToWait;
0365:            }
0366:
0367:            /**
0368:             * Getter for the query to be used to check a connection
0369:             * @return The query
0370:             */
0371:            public String getPoolPingQuery() {
0372:                return poolPingQuery;
0373:            }
0374:
0375:            /**
0376:             * Getter to tell if we should use the ping query
0377:             * @return True if we need to check a connection before using it
0378:             */
0379:            public boolean isPoolPingEnabled() {
0380:                return poolPingEnabled;
0381:            }
0382:
0383:            /**
0384:             * Getter for the age of connections that should be pinged before using
0385:             * @return The age
0386:             */
0387:            public int getPoolPingConnectionsOlderThan() {
0388:                return poolPingConnectionsOlderThan;
0389:            }
0390:
0391:            private int getExpectedConnectionTypeCode() {
0392:                return expectedConnectionTypeCode;
0393:            }
0394:
0395:            /**
0396:             * Getter for the number of connection requests made
0397:             * @return The number of connection requests made
0398:             */
0399:            public long getRequestCount() {
0400:                synchronized (POOL_LOCK) {
0401:                    return requestCount;
0402:                }
0403:            }
0404:
0405:            /**
0406:             * Getter for the average time required to get a connection to the database
0407:             * @return The average time
0408:             */
0409:            public long getAverageRequestTime() {
0410:                synchronized (POOL_LOCK) {
0411:                    return requestCount == 0 ? 0 : accumulatedRequestTime
0412:                            / requestCount;
0413:                }
0414:            }
0415:
0416:            /**
0417:             * Getter for the average time spent waiting for connections that were in use
0418:             * @return The average time
0419:             */
0420:            public long getAverageWaitTime() {
0421:                synchronized (POOL_LOCK) {
0422:                    return hadToWaitCount == 0 ? 0 : accumulatedWaitTime
0423:                            / hadToWaitCount;
0424:                }
0425:            }
0426:
0427:            /**
0428:             * Getter for the number of requests that had to wait for connections that were in use
0429:             * @return The number of requests that had to wait
0430:             */
0431:            public long getHadToWaitCount() {
0432:                synchronized (POOL_LOCK) {
0433:                    return hadToWaitCount;
0434:                }
0435:            }
0436:
0437:            /**
0438:             * Getter for the number of invalid connections that were found in the pool
0439:             * @return The number of invalid connections
0440:             */
0441:            public long getBadConnectionCount() {
0442:                synchronized (POOL_LOCK) {
0443:                    return badConnectionCount;
0444:                }
0445:            }
0446:
0447:            /**
0448:             * Getter for the number of connections that were claimed before they were returned
0449:             * @return The number of connections
0450:             */
0451:            public long getClaimedOverdueConnectionCount() {
0452:                synchronized (POOL_LOCK) {
0453:                    return claimedOverdueConnectionCount;
0454:                }
0455:            }
0456:
0457:            /**
0458:             * Getter for the average age of overdue connections
0459:             * @return The average age
0460:             */
0461:            public long getAverageOverdueCheckoutTime() {
0462:                synchronized (POOL_LOCK) {
0463:                    return claimedOverdueConnectionCount == 0 ? 0
0464:                            : accumulatedCheckoutTimeOfOverdueConnections
0465:                                    / claimedOverdueConnectionCount;
0466:                }
0467:            }
0468:
0469:            /**
0470:             * Getter for the average age of a connection checkout
0471:             * @return The average age
0472:             */
0473:            public long getAverageCheckoutTime() {
0474:                synchronized (POOL_LOCK) {
0475:                    return requestCount == 0 ? 0 : accumulatedCheckoutTime
0476:                            / requestCount;
0477:                }
0478:            }
0479:
0480:            /**
0481:             * Returns the status of the connection pool
0482:             * @return The status
0483:             */
0484:            public String getStatus() {
0485:                StringBuffer buffer = new StringBuffer();
0486:
0487:                buffer
0488:                        .append("\n===============================================================");
0489:                buffer.append("\n jdbcDriver                     ").append(
0490:                        jdbcDriver);
0491:                buffer.append("\n jdbcUrl                        ").append(
0492:                        jdbcUrl);
0493:                buffer.append("\n jdbcUsername                   ").append(
0494:                        jdbcUsername);
0495:                buffer.append("\n jdbcPassword                   ").append(
0496:                        (jdbcPassword == null ? "NULL" : "************"));
0497:                buffer.append("\n poolMaxActiveConnections       ").append(
0498:                        poolMaximumActiveConnections);
0499:                buffer.append("\n poolMaxIdleConnections         ").append(
0500:                        poolMaximumIdleConnections);
0501:                buffer.append("\n poolMaxCheckoutTime            "
0502:                        + poolMaximumCheckoutTime);
0503:                buffer.append("\n poolTimeToWait                 "
0504:                        + poolTimeToWait);
0505:                buffer.append("\n poolPingEnabled                "
0506:                        + poolPingEnabled);
0507:                buffer.append("\n poolPingQuery                  "
0508:                        + poolPingQuery);
0509:                buffer.append("\n poolPingConnectionsOlderThan   "
0510:                        + poolPingConnectionsOlderThan);
0511:                buffer.append("\n poolPingConnectionsNotUsedFor  "
0512:                        + poolPingConnectionsNotUsedFor);
0513:                buffer
0514:                        .append("\n --------------------------------------------------------------");
0515:                buffer.append("\n activeConnections              "
0516:                        + activeConnections.size());
0517:                buffer.append("\n idleConnections                "
0518:                        + idleConnections.size());
0519:                buffer.append("\n requestCount                   "
0520:                        + getRequestCount());
0521:                buffer.append("\n averageRequestTime             "
0522:                        + getAverageRequestTime());
0523:                buffer.append("\n averageCheckoutTime            "
0524:                        + getAverageCheckoutTime());
0525:                buffer.append("\n claimedOverdue                 "
0526:                        + getClaimedOverdueConnectionCount());
0527:                buffer.append("\n averageOverdueCheckoutTime     "
0528:                        + getAverageOverdueCheckoutTime());
0529:                buffer.append("\n hadToWait                      "
0530:                        + getHadToWaitCount());
0531:                buffer.append("\n averageWaitTime                "
0532:                        + getAverageWaitTime());
0533:                buffer.append("\n badConnectionCount             "
0534:                        + getBadConnectionCount());
0535:                buffer
0536:                        .append("\n===============================================================");
0537:                return buffer.toString();
0538:            }
0539:
0540:            /**
0541:             * Closes all of the connections in the pool
0542:             */
0543:            public void forceCloseAll() {
0544:                synchronized (POOL_LOCK) {
0545:                    for (int i = activeConnections.size(); i > 0; i--) {
0546:                        try {
0547:                            SimplePooledConnection conn = (SimplePooledConnection) activeConnections
0548:                                    .remove(i - 1);
0549:                            conn.invalidate();
0550:
0551:                            Connection realConn = conn.getRealConnection();
0552:                            if (!realConn.getAutoCommit()) {
0553:                                realConn.rollback();
0554:                            }
0555:                            realConn.close();
0556:                        } catch (Exception e) {
0557:                            // ignore
0558:                        }
0559:                    }
0560:                    for (int i = idleConnections.size(); i > 0; i--) {
0561:                        try {
0562:                            SimplePooledConnection conn = (SimplePooledConnection) idleConnections
0563:                                    .remove(i - 1);
0564:                            conn.invalidate();
0565:
0566:                            Connection realConn = conn.getRealConnection();
0567:                            if (!realConn.getAutoCommit()) {
0568:                                realConn.rollback();
0569:                            }
0570:                            realConn.close();
0571:                        } catch (Exception e) {
0572:                            // ignore
0573:                        }
0574:                    }
0575:                }
0576:                if (log.isDebugEnabled()) {
0577:                    log
0578:                            .debug("SimpleDataSource forcefully closed/removed all connections.");
0579:                }
0580:            }
0581:
0582:            private void pushConnection(SimplePooledConnection conn)
0583:                    throws SQLException {
0584:
0585:                synchronized (POOL_LOCK) {
0586:                    activeConnections.remove(conn);
0587:                    if (conn.isValid()) {
0588:                        if (idleConnections.size() < poolMaximumIdleConnections
0589:                                && conn.getConnectionTypeCode() == getExpectedConnectionTypeCode()) {
0590:                            accumulatedCheckoutTime += conn.getCheckoutTime();
0591:                            if (!conn.getRealConnection().getAutoCommit()) {
0592:                                conn.getRealConnection().rollback();
0593:                            }
0594:                            SimplePooledConnection newConn = new SimplePooledConnection(
0595:                                    conn.getRealConnection(), this );
0596:                            idleConnections.add(newConn);
0597:                            newConn.setCreatedTimestamp(conn
0598:                                    .getCreatedTimestamp());
0599:                            newConn.setLastUsedTimestamp(conn
0600:                                    .getLastUsedTimestamp());
0601:                            conn.invalidate();
0602:                            if (log.isDebugEnabled()) {
0603:                                log.debug("Returned connection "
0604:                                        + newConn.getRealHashCode()
0605:                                        + " to pool.");
0606:                            }
0607:                            POOL_LOCK.notifyAll();
0608:                        } else {
0609:                            accumulatedCheckoutTime += conn.getCheckoutTime();
0610:                            if (!conn.getRealConnection().getAutoCommit()) {
0611:                                conn.getRealConnection().rollback();
0612:                            }
0613:                            conn.getRealConnection().close();
0614:                            if (log.isDebugEnabled()) {
0615:                                log.debug("Closed connection "
0616:                                        + conn.getRealHashCode() + ".");
0617:                            }
0618:                            conn.invalidate();
0619:                        }
0620:                    } else {
0621:                        if (log.isDebugEnabled()) {
0622:                            log
0623:                                    .debug("A bad connection ("
0624:                                            + conn.getRealHashCode()
0625:                                            + ") attempted to return to the pool, discarding connection.");
0626:                        }
0627:                        badConnectionCount++;
0628:                    }
0629:                }
0630:            }
0631:
0632:            private SimplePooledConnection popConnection(String username,
0633:                    String password) throws SQLException {
0634:                boolean countedWait = false;
0635:                SimplePooledConnection conn = null;
0636:                long t = System.currentTimeMillis();
0637:                int localBadConnectionCount = 0;
0638:
0639:                while (conn == null) {
0640:                    synchronized (POOL_LOCK) {
0641:                        if (idleConnections.size() > 0) {
0642:                            // Pool has available connection
0643:                            conn = (SimplePooledConnection) idleConnections
0644:                                    .remove(0);
0645:                            if (log.isDebugEnabled()) {
0646:                                log.debug("Checked out connection "
0647:                                        + conn.getRealHashCode()
0648:                                        + " from pool.");
0649:                            }
0650:                        } else {
0651:                            // Pool does not have available connection
0652:                            if (activeConnections.size() < poolMaximumActiveConnections) {
0653:                                // Can create new connection
0654:                                if (useDriverProps) {
0655:                                    conn = new SimplePooledConnection(
0656:                                            DriverManager.getConnection(
0657:                                                    jdbcUrl, driverProps), this );
0658:                                } else {
0659:                                    conn = new SimplePooledConnection(
0660:                                            DriverManager.getConnection(
0661:                                                    jdbcUrl, jdbcUsername,
0662:                                                    jdbcPassword), this );
0663:                                }
0664:                                Connection realConn = conn.getRealConnection();
0665:                                if (realConn.getAutoCommit() != jdbcDefaultAutoCommit) {
0666:                                    realConn
0667:                                            .setAutoCommit(jdbcDefaultAutoCommit);
0668:                                }
0669:                                if (log.isDebugEnabled()) {
0670:                                    log.debug("Created connection "
0671:                                            + conn.getRealHashCode() + ".");
0672:                                }
0673:                            } else {
0674:                                // Cannot create new connection
0675:                                SimplePooledConnection oldestActiveConnection = (SimplePooledConnection) activeConnections
0676:                                        .get(0);
0677:                                long longestCheckoutTime = oldestActiveConnection
0678:                                        .getCheckoutTime();
0679:                                if (longestCheckoutTime > poolMaximumCheckoutTime) {
0680:                                    // Can claim overdue connection
0681:                                    claimedOverdueConnectionCount++;
0682:                                    accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
0683:                                    accumulatedCheckoutTime += longestCheckoutTime;
0684:                                    activeConnections
0685:                                            .remove(oldestActiveConnection);
0686:                                    if (!oldestActiveConnection
0687:                                            .getRealConnection()
0688:                                            .getAutoCommit()) {
0689:                                        oldestActiveConnection
0690:                                                .getRealConnection().rollback();
0691:                                    }
0692:                                    conn = new SimplePooledConnection(
0693:                                            oldestActiveConnection
0694:                                                    .getRealConnection(), this );
0695:                                    oldestActiveConnection.invalidate();
0696:                                    if (log.isDebugEnabled()) {
0697:                                        log.debug("Claimed overdue connection "
0698:                                                + conn.getRealHashCode() + ".");
0699:                                    }
0700:                                } else {
0701:                                    // Must wait
0702:                                    try {
0703:                                        if (!countedWait) {
0704:                                            hadToWaitCount++;
0705:                                            countedWait = true;
0706:                                        }
0707:                                        if (log.isDebugEnabled()) {
0708:                                            log
0709:                                                    .debug("Waiting as long as "
0710:                                                            + poolTimeToWait
0711:                                                            + " milliseconds for connection.");
0712:                                        }
0713:                                        long wt = System.currentTimeMillis();
0714:                                        POOL_LOCK.wait(poolTimeToWait);
0715:                                        accumulatedWaitTime += System
0716:                                                .currentTimeMillis()
0717:                                                - wt;
0718:                                    } catch (InterruptedException e) {
0719:                                        break;
0720:                                    }
0721:                                }
0722:                            }
0723:                        }
0724:                        if (conn != null) {
0725:                            if (conn.isValid()) {
0726:                                if (!conn.getRealConnection().getAutoCommit()) {
0727:                                    conn.getRealConnection().rollback();
0728:                                }
0729:                                conn
0730:                                        .setConnectionTypeCode(assembleConnectionTypeCode(
0731:                                                jdbcUrl, username, password));
0732:                                conn.setCheckoutTimestamp(System
0733:                                        .currentTimeMillis());
0734:                                conn.setLastUsedTimestamp(System
0735:                                        .currentTimeMillis());
0736:                                activeConnections.add(conn);
0737:                                requestCount++;
0738:                                accumulatedRequestTime += System
0739:                                        .currentTimeMillis()
0740:                                        - t;
0741:                            } else {
0742:                                if (log.isDebugEnabled()) {
0743:                                    log
0744:                                            .debug("A bad connection ("
0745:                                                    + conn.getRealHashCode()
0746:                                                    + ") was returned from the pool, getting another connection.");
0747:                                }
0748:                                badConnectionCount++;
0749:                                localBadConnectionCount++;
0750:                                conn = null;
0751:                                if (localBadConnectionCount > (poolMaximumIdleConnections + 3)) {
0752:                                    if (log.isDebugEnabled()) {
0753:                                        log
0754:                                                .debug("SimpleDataSource: Could not get a good connection to the database.");
0755:                                    }
0756:                                    throw new SQLException(
0757:                                            "SimpleDataSource: Could not get a good connection to the database.");
0758:                                }
0759:                            }
0760:                        }
0761:                    }
0762:
0763:                }
0764:
0765:                if (conn == null) {
0766:                    if (log.isDebugEnabled()) {
0767:                        log
0768:                                .debug("SimpleDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
0769:                    }
0770:                    throw new SQLException(
0771:                            "SimpleDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
0772:                }
0773:
0774:                return conn;
0775:            }
0776:
0777:            /**
0778:             * Method to check to see if a connection is still usable
0779:             *
0780:             * @param conn - the connection to check
0781:             * @return True if the connection is still usable
0782:             */
0783:            private boolean pingConnection(SimplePooledConnection conn) {
0784:                boolean result = true;
0785:
0786:                try {
0787:                    result = !conn.getRealConnection().isClosed();
0788:                } catch (SQLException e) {
0789:                    if (log.isDebugEnabled()) {
0790:                        log.debug("Connection " + conn.getRealHashCode()
0791:                                + " is BAD: " + e.getMessage());
0792:                    }
0793:                    result = false;
0794:                }
0795:
0796:                if (result) {
0797:                    if (poolPingEnabled) {
0798:                        if ((poolPingConnectionsOlderThan > 0 && conn.getAge() > poolPingConnectionsOlderThan)
0799:                                || (poolPingConnectionsNotUsedFor > 0 && conn
0800:                                        .getTimeElapsedSinceLastUse() > poolPingConnectionsNotUsedFor)) {
0801:
0802:                            try {
0803:                                if (log.isDebugEnabled()) {
0804:                                    log.debug("Testing connection "
0805:                                            + conn.getRealHashCode() + " ...");
0806:                                }
0807:                                Connection realConn = conn.getRealConnection();
0808:                                Statement statement = realConn
0809:                                        .createStatement();
0810:                                ResultSet rs = statement
0811:                                        .executeQuery(poolPingQuery);
0812:                                rs.close();
0813:                                statement.close();
0814:                                if (!realConn.getAutoCommit()) {
0815:                                    realConn.rollback();
0816:                                }
0817:                                result = true;
0818:                                if (log.isDebugEnabled()) {
0819:                                    log.debug("Connection "
0820:                                            + conn.getRealHashCode()
0821:                                            + " is GOOD!");
0822:                                }
0823:                            } catch (Exception e) {
0824:                                log.warn("Execution of ping query '"
0825:                                        + poolPingQuery + "' failed: "
0826:                                        + e.getMessage());
0827:                                try {
0828:                                    conn.getRealConnection().close();
0829:                                } catch (Exception e2) {
0830:                                    //ignore
0831:                                }
0832:                                result = false;
0833:                                if (log.isDebugEnabled()) {
0834:                                    log.debug("Connection "
0835:                                            + conn.getRealHashCode()
0836:                                            + " is BAD: " + e.getMessage());
0837:                                }
0838:                            }
0839:                        }
0840:                    }
0841:                }
0842:                return result;
0843:            }
0844:
0845:            /**
0846:             * Unwraps a pooled connection to get to the 'real' connection
0847:             *
0848:             * @param conn - the pooled connection to unwrap
0849:             * @return The 'real' connection
0850:             */
0851:            public static Connection unwrapConnection(Connection conn) {
0852:                if (conn instanceof  SimplePooledConnection) {
0853:                    return ((SimplePooledConnection) conn).getRealConnection();
0854:                } else {
0855:                    return conn;
0856:                }
0857:            }
0858:
0859:            protected void finalize() throws Throwable {
0860:                forceCloseAll();
0861:            }
0862:
0863:            /**
0864:             * ---------------------------------------------------------------------------------------
0865:             * SimplePooledConnection
0866:             * ---------------------------------------------------------------------------------------
0867:             */
0868:            private static class SimplePooledConnection implements 
0869:                    InvocationHandler {
0870:
0871:                private static final String CLOSE = "close";
0872:                private static final Class[] IFACES = new Class[] { Connection.class };
0873:
0874:                private int hashCode = 0;
0875:                private SimpleDataSource dataSource;
0876:                private Connection realConnection;
0877:                private Connection proxyConnection;
0878:                private long checkoutTimestamp;
0879:                private long createdTimestamp;
0880:                private long lastUsedTimestamp;
0881:                private int connectionTypeCode;
0882:                private boolean valid;
0883:
0884:                /**
0885:                 * Constructor for SimplePooledConnection that uses the Connection and SimpleDataSource passed in
0886:                 *
0887:                 * @param connection - the connection that is to be presented as a pooled connection
0888:                 * @param dataSource - the dataSource that the connection is from
0889:                 */
0890:                public SimplePooledConnection(Connection connection,
0891:                        SimpleDataSource dataSource) {
0892:                    this .hashCode = connection.hashCode();
0893:                    this .realConnection = connection;
0894:                    this .dataSource = dataSource;
0895:                    this .createdTimestamp = System.currentTimeMillis();
0896:                    this .lastUsedTimestamp = System.currentTimeMillis();
0897:                    this .valid = true;
0898:
0899:                    proxyConnection = (Connection) Proxy.newProxyInstance(
0900:                            Connection.class.getClassLoader(), IFACES, this );
0901:                }
0902:
0903:                /**
0904:                 * Invalidates the connection
0905:                 */
0906:                public void invalidate() {
0907:                    valid = false;
0908:                }
0909:
0910:                /**
0911:                 * Method to see if the connection is usable
0912:                 *
0913:                 * @return True if the connection is usable
0914:                 */
0915:                public boolean isValid() {
0916:                    return valid && realConnection != null
0917:                            && dataSource.pingConnection(this );
0918:                }
0919:
0920:                /**
0921:                 * Getter for the *real* connection that this wraps
0922:                 * @return The connection
0923:                 */
0924:                public Connection getRealConnection() {
0925:                    return realConnection;
0926:                }
0927:
0928:                /**
0929:                 * Getter for the proxy for the connection
0930:                 * @return The proxy
0931:                 */
0932:                public Connection getProxyConnection() {
0933:                    return proxyConnection;
0934:                }
0935:
0936:                /**
0937:                 * Gets the hashcode of the real connection (or 0 if it is null)
0938:                 *
0939:                 * @return The hashcode of the real connection (or 0 if it is null)
0940:                 */
0941:                public int getRealHashCode() {
0942:                    if (realConnection == null) {
0943:                        return 0;
0944:                    } else {
0945:                        return realConnection.hashCode();
0946:                    }
0947:                }
0948:
0949:                /**
0950:                 * Getter for the connection type (based on url + user + password)
0951:                 * @return The connection type
0952:                 */
0953:                public int getConnectionTypeCode() {
0954:                    return connectionTypeCode;
0955:                }
0956:
0957:                /**
0958:                 * Setter for the connection type
0959:                 * @param connectionTypeCode - the connection type
0960:                 */
0961:                public void setConnectionTypeCode(int connectionTypeCode) {
0962:                    this .connectionTypeCode = connectionTypeCode;
0963:                }
0964:
0965:                /**
0966:                 * Getter for the time that the connection was created
0967:                 * @return The creation timestamp
0968:                 */
0969:                public long getCreatedTimestamp() {
0970:                    return createdTimestamp;
0971:                }
0972:
0973:                /**
0974:                 * Setter for the time that the connection was created
0975:                 * @param createdTimestamp - the timestamp
0976:                 */
0977:                public void setCreatedTimestamp(long createdTimestamp) {
0978:                    this .createdTimestamp = createdTimestamp;
0979:                }
0980:
0981:                /**
0982:                 * Getter for the time that the connection was last used
0983:                 * @return - the timestamp
0984:                 */
0985:                public long getLastUsedTimestamp() {
0986:                    return lastUsedTimestamp;
0987:                }
0988:
0989:                /**
0990:                 * Setter for the time that the connection was last used
0991:                 * @param lastUsedTimestamp - the timestamp
0992:                 */
0993:                public void setLastUsedTimestamp(long lastUsedTimestamp) {
0994:                    this .lastUsedTimestamp = lastUsedTimestamp;
0995:                }
0996:
0997:                /**
0998:                 * Getter for the time since this connection was last used
0999:                 * @return - the time since the last use
1000:                 */
1001:                public long getTimeElapsedSinceLastUse() {
1002:                    return System.currentTimeMillis() - lastUsedTimestamp;
1003:                }
1004:
1005:                /**
1006:                 * Getter for the age of the connection
1007:                 * @return the age
1008:                 */
1009:                public long getAge() {
1010:                    return System.currentTimeMillis() - createdTimestamp;
1011:                }
1012:
1013:                /**
1014:                 * Getter for the timestamp that this connection was checked out
1015:                 * @return the timestamp
1016:                 */
1017:                public long getCheckoutTimestamp() {
1018:                    return checkoutTimestamp;
1019:                }
1020:
1021:                /**
1022:                 * Setter for the timestamp that this connection was checked out
1023:                 * @param timestamp the timestamp
1024:                 */
1025:                public void setCheckoutTimestamp(long timestamp) {
1026:                    this .checkoutTimestamp = timestamp;
1027:                }
1028:
1029:                /**
1030:                 * Getter for the time that this connection has been checked out
1031:                 * @return the time
1032:                 */
1033:                public long getCheckoutTime() {
1034:                    return System.currentTimeMillis() - checkoutTimestamp;
1035:                }
1036:
1037:                private Connection getValidConnection() {
1038:                    if (!valid) {
1039:                        throw new RuntimeException(
1040:                                "Error accessing SimplePooledConnection. Connection is invalid.");
1041:                    }
1042:                    return realConnection;
1043:                }
1044:
1045:                public int hashCode() {
1046:                    return hashCode;
1047:                }
1048:
1049:                /**
1050:                 * Allows comparing this connection to another
1051:                 *
1052:                 * @param obj - the other connection to test for equality
1053:                 * @see java.lang.Object#equals(java.lang.Object)
1054:                 */
1055:                public boolean equals(Object obj) {
1056:                    if (obj instanceof  SimplePooledConnection) {
1057:                        return realConnection.hashCode() == (((SimplePooledConnection) obj).realConnection
1058:                                .hashCode());
1059:                    } else if (obj instanceof  Connection) {
1060:                        return hashCode == obj.hashCode();
1061:                    } else {
1062:                        return false;
1063:                    }
1064:                }
1065:
1066:                // **********************************
1067:                // Implemented Connection Methods -- Now handled by proxy
1068:                // **********************************
1069:
1070:                /**
1071:                 * Required for InvocationHandler implementation.
1072:                 *
1073:                 * @param proxy  - not used
1074:                 * @param method - the method to be executed
1075:                 * @param args   - the parameters to be passed to the method
1076:                 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
1077:                 */
1078:                public Object invoke(Object proxy, Method method, Object[] args)
1079:                        throws Throwable {
1080:                    String methodName = method.getName();
1081:                    if (CLOSE.hashCode() == methodName.hashCode()
1082:                            && CLOSE.equals(methodName)) {
1083:                        dataSource.pushConnection(this );
1084:                        return null;
1085:                    } else {
1086:                        try {
1087:                            return method.invoke(getValidConnection(), args);
1088:                        } catch (Throwable t) {
1089:                            throw ClassInfo.unwrapThrowable(t);
1090:                        }
1091:                    }
1092:                }
1093:
1094:                public Statement createStatement() throws SQLException {
1095:                    return getValidConnection().createStatement();
1096:                }
1097:
1098:                public PreparedStatement prepareStatement(String sql)
1099:                        throws SQLException {
1100:                    return getValidConnection().prepareStatement(sql);
1101:                }
1102:
1103:                public CallableStatement prepareCall(String sql)
1104:                        throws SQLException {
1105:                    return getValidConnection().prepareCall(sql);
1106:                }
1107:
1108:                public String nativeSQL(String sql) throws SQLException {
1109:                    return getValidConnection().nativeSQL(sql);
1110:                }
1111:
1112:                public void setAutoCommit(boolean autoCommit)
1113:                        throws SQLException {
1114:                    getValidConnection().setAutoCommit(autoCommit);
1115:                }
1116:
1117:                public boolean getAutoCommit() throws SQLException {
1118:                    return getValidConnection().getAutoCommit();
1119:                }
1120:
1121:                public void commit() throws SQLException {
1122:                    getValidConnection().commit();
1123:                }
1124:
1125:                public void rollback() throws SQLException {
1126:                    getValidConnection().rollback();
1127:                }
1128:
1129:                public void close() throws SQLException {
1130:                    dataSource.pushConnection(this );
1131:                }
1132:
1133:                public boolean isClosed() throws SQLException {
1134:                    return getValidConnection().isClosed();
1135:                }
1136:
1137:                public DatabaseMetaData getMetaData() throws SQLException {
1138:                    return getValidConnection().getMetaData();
1139:                }
1140:
1141:                public void setReadOnly(boolean readOnly) throws SQLException {
1142:                    getValidConnection().setReadOnly(readOnly);
1143:                }
1144:
1145:                public boolean isReadOnly() throws SQLException {
1146:                    return getValidConnection().isReadOnly();
1147:                }
1148:
1149:                public void setCatalog(String catalog) throws SQLException {
1150:                    getValidConnection().setCatalog(catalog);
1151:                }
1152:
1153:                public String getCatalog() throws SQLException {
1154:                    return getValidConnection().getCatalog();
1155:                }
1156:
1157:                public void setTransactionIsolation(int level)
1158:                        throws SQLException {
1159:                    getValidConnection().setTransactionIsolation(level);
1160:                }
1161:
1162:                public int getTransactionIsolation() throws SQLException {
1163:                    return getValidConnection().getTransactionIsolation();
1164:                }
1165:
1166:                public SQLWarning getWarnings() throws SQLException {
1167:                    return getValidConnection().getWarnings();
1168:                }
1169:
1170:                public void clearWarnings() throws SQLException {
1171:                    getValidConnection().clearWarnings();
1172:                }
1173:
1174:                public Statement createStatement(int resultSetType,
1175:                        int resultSetConcurrency) throws SQLException {
1176:                    return getValidConnection().createStatement(resultSetType,
1177:                            resultSetConcurrency);
1178:                }
1179:
1180:                public PreparedStatement prepareStatement(String sql,
1181:                        int resultSetType, int resultSetConcurrency)
1182:                        throws SQLException {
1183:                    return getValidConnection().prepareCall(sql, resultSetType,
1184:                            resultSetConcurrency);
1185:                }
1186:
1187:                public CallableStatement prepareCall(String sql,
1188:                        int resultSetType, int resultSetConcurrency)
1189:                        throws SQLException {
1190:                    return getValidConnection().prepareCall(sql, resultSetType,
1191:                            resultSetConcurrency);
1192:                }
1193:
1194:                public Map getTypeMap() throws SQLException {
1195:                    return getValidConnection().getTypeMap();
1196:                }
1197:
1198:                public void setTypeMap(Map map) throws SQLException {
1199:                    getValidConnection().setTypeMap(map);
1200:                }
1201:
1202:                // **********************************
1203:                // JDK 1.4 JDBC 3.0 Methods below
1204:                // **********************************
1205:
1206:                public void setHoldability(int holdability) throws SQLException {
1207:                    getValidConnection().setHoldability(holdability);
1208:                }
1209:
1210:                public int getHoldability() throws SQLException {
1211:                    return getValidConnection().getHoldability();
1212:                }
1213:
1214:                public Savepoint setSavepoint() throws SQLException {
1215:                    return getValidConnection().setSavepoint();
1216:                }
1217:
1218:                public Savepoint setSavepoint(String name) throws SQLException {
1219:                    return getValidConnection().setSavepoint(name);
1220:                }
1221:
1222:                public void rollback(Savepoint savepoint) throws SQLException {
1223:                    getValidConnection().rollback(savepoint);
1224:                }
1225:
1226:                public void releaseSavepoint(Savepoint savepoint)
1227:                        throws SQLException {
1228:                    getValidConnection().releaseSavepoint(savepoint);
1229:                }
1230:
1231:                public Statement createStatement(int resultSetType,
1232:                        int resultSetConcurrency, int resultSetHoldability)
1233:                        throws SQLException {
1234:                    return getValidConnection().createStatement(resultSetType,
1235:                            resultSetConcurrency, resultSetHoldability);
1236:                }
1237:
1238:                public PreparedStatement prepareStatement(String sql,
1239:                        int resultSetType, int resultSetConcurrency,
1240:                        int resultSetHoldability) throws SQLException {
1241:                    return getValidConnection().prepareStatement(sql,
1242:                            resultSetType, resultSetConcurrency,
1243:                            resultSetHoldability);
1244:                }
1245:
1246:                public CallableStatement prepareCall(String sql,
1247:                        int resultSetType, int resultSetConcurrency,
1248:                        int resultSetHoldability) throws SQLException {
1249:                    return getValidConnection().prepareCall(sql, resultSetType,
1250:                            resultSetConcurrency, resultSetHoldability);
1251:                }
1252:
1253:                public PreparedStatement prepareStatement(String sql,
1254:                        int autoGeneratedKeys) throws SQLException {
1255:                    return getValidConnection().prepareStatement(sql,
1256:                            autoGeneratedKeys);
1257:                }
1258:
1259:                public PreparedStatement prepareStatement(String sql,
1260:                        int columnIndexes[]) throws SQLException {
1261:                    return getValidConnection().prepareStatement(sql,
1262:                            columnIndexes);
1263:                }
1264:
1265:                public PreparedStatement prepareStatement(String sql,
1266:                        String columnNames[]) throws SQLException {
1267:                    return getValidConnection().prepareStatement(sql,
1268:                            columnNames);
1269:                }
1270:
1271:            }
1272:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.