Source Code Cross Referenced for ConnectionPool.java in  » Database-JDBC-Connection-Pool » SmartPool » org » smartlib » pool » core » 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 » SmartPool » org.smartlib.pool.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#) ConnectionPool 1.0 02/08/01
003:         */
004:
005:        package org.smartlib.pool.core;
006:
007:        import org.apache.log4j.Logger;
008:
009:        import java.util.*;
010:        import java.sql.*;
011:
012:        /**
013:         * This class implements the Pool interface and thus is responsible for 
014:         * managing a single pool of connections.
015:         */
016:
017:        public class ConnectionPool implements  Pool, PoolMonitor {
018:
019:            private PoolConfig config;
020:            private final String name;
021:            private final Debugger debug;
022:            private int currentPoolSize = 0;
023:            private int usedConnections = 0;
024:            private Vector connectionList;
025:            private Vector connectionListenerList;
026:            private Thread pollerThread;
027:            private ConnectionProvider connProvider = null;
028:            private String validatorQuery = null;
029:            private volatile boolean shutDown = false;
030:            private Hashtable connectionHash = new Hashtable();
031:
032:            Logger logger = Logger.getLogger(ConnectionPool.class);
033:
034:            /**
035:             * This method draws a raw connection from the database.
036:             */
037:            private Connection loadConnection() throws ConnectionPoolException {
038:
039:                try {
040:                    Class.forName(config.getDriver());
041:                } catch (ClassNotFoundException classNotFound) {
042:                    throw new ConnectionPoolException("Could not load Driver",
043:                            classNotFound);
044:                }
045:                Connection con = null;
046:                try {
047:                    con = DriverManager.getConnection(
048:                            config.getConnectionStringByName(name)
049:                                    .getConnectString(), config.getUserName(),
050:                            config.getPassword());
051:                } catch (Exception e) {
052:                    throw new ConnectionPoolException(
053:                            "Could not obtain Connection", e);
054:                }
055:                currentPoolSize++;
056:                return con;
057:
058:            }
059:
060:            /**
061:             * @return Vector of connections in use.
062:             */
063:            public Vector getConnectionsInUse() {
064:
065:                return connectionList;
066:
067:            }
068:
069:            /**
070:             * @return Vector of registered ConnectionLeakListeners.
071:             */
072:            public Vector getConnectionLeakListeners() {
073:
074:                return connectionListenerList;
075:
076:            }
077:
078:            /**
079:             * @return Number of free connections in the pool.
080:             */
081:            public int getNoOfFreeConnections() {
082:
083:                return (currentPoolSize - usedConnections);
084:
085:            }
086:
087:            /**
088:             * This method returns an instance of ConfigMonitor.
089:             * @return ConfigMonitor for monitoring the configuration of the pool at
090:             * 			runtime.
091:             */
092:            public ConfigMonitor getConfigMonitor() {
093:
094:                return (ConfigMonitor) config;
095:
096:            }
097:
098:            public String getName() {
099:                return name;
100:            }
101:
102:            /**
103:             * This method draws the initial raw connections.
104:             */
105:            private void initialiseConnections() throws ConnectionPoolException {
106:
107:                try {
108:                    int minConnections = config.getMinConnections();
109:                    for (int i = 0; i < minConnections; i++) {
110:                        connectionHash.put(loadConnection(), Boolean.TRUE);
111:                    }
112:                } catch (Exception e) {
113:                    throw new ConnectionPoolException(
114:                            "Could not load initial connection", e);
115:                }
116:
117:            }
118:
119:            /*
120:             * This method is called when the existing connection is wrapped to another
121:             * pool.
122:             */
123:            private void returnConnectionToOtherPool(Connection conn)
124:                    throws Exception {
125:
126:                connProvider.returnConnection(conn);
127:
128:            }
129:
130:            /**
131:             * Constructor initialises the pool as per the configuration specified by
132:             * <code>config</code>
133:             */
134:            ConnectionPool(PoolConfig config, String name)
135:                    throws ConnectionPoolException {
136:
137:                this .name = name;
138:                this .config = config;
139:                try {
140:                    if (config.getConnectionLoaderClass() != null)
141:                        connProvider = (ConnectionProvider) getClass()
142:                                .getClassLoader().loadClass(
143:                                        config.getConnectionLoaderClassByName(
144:                                                name)
145:                                                .getConnectionLoaderClass())
146:                                .newInstance();
147:                } catch (Exception exp) {
148:                    throw new ConnectionPoolException(
149:                            "Error loading Connection Loader Class", exp);
150:                }
151:                if (connProvider == null)
152:                    initialiseConnections();
153:
154:                debug = new Debugger(name, true);
155:                connectionList = new Vector(config.getMinConnections(), config
156:                        .getIncrement());
157:                connectionListenerList = new Vector();
158:                try {
159:                    if (config.getDefaultListener() != null) {
160:                        String defaultListener = config.getDefaultListener();
161:                        addConnectionLeakListener((ConnectionLeakListener) getClass()
162:                                .getClassLoader().loadClass(defaultListener)
163:                                .newInstance());
164:                    }
165:                } catch (Exception e) {
166:                    throw new ConnectionPoolException("Could not load class "
167:                            + config.getDefaultListener(), e);
168:                }
169:                if (config.isDetectLeaks()) {
170:                    pollerThread = new Thread(new ConnectionLeakPollThread(
171:                            connectionList, connectionListenerList, name,
172:                            config.getPollThreadTime(),
173:                            config.getLeakTimeOut(), this ));
174:                    pollerThread.start();
175:                }
176:
177:                validatorQuery = config.getValidatorQuery();
178:
179:            }
180:
181:            /**
182:             * This method returns the current size of the pool.
183:             * @return Current size of the pool.
184:             */
185:            public int getCurrentPoolSize() {
186:
187:                return currentPoolSize;
188:
189:            }
190:
191:            /**
192:             * This method returns a Connection from the connection pool.
193:             * The owner of this pool is marked as N/A indicating unknown/anonymous.
194:             *
195:             * <b>Note: This method blocks if the pool size has reached it's
196:             * maximum size and no free connections are available
197:             * until a free connection is available.</b> The time period for which this
198:             * method blocks depends on the connection-wait-time-out specified in
199:             * the configuration file.
200:             *
201:             *
202:             * @return Connection from the pool.
203:             * @exception ConnectionPoolException if there is any problem
204:             *		getting connection.
205:             */
206:            public Connection getConnection() throws ConnectionPoolException {
207:
208:                if (config.isAllowAnonymousConnections())
209:                    return getConnection("N/A");
210:                else
211:                    throw new ConnectionPoolException(
212:                            "You are not allowed to take anonumous connections, please provide an owner name");
213:
214:            }
215:
216:            // Checks if the Connection is valid
217:            private boolean checkIfValid(Connection conn) {
218:
219:                try {
220:                    debug.print(" Checking Connection for '" + validatorQuery
221:                            + "'");
222:                    if (validatorQuery != null
223:                            && !validatorQuery.trim().equals("")) {
224:                        Statement stmt = conn.createStatement();
225:                        boolean bool = stmt.execute(validatorQuery);
226:                        stmt.close();
227:                        return bool;
228:                    } else {
229:                        return true;
230:                    }
231:                } catch (SQLException exp) {
232:                    if (logger.isDebugEnabled()) {
233:                        logger
234:                                .debug(
235:                                        "Exception occurred while trying to test connection validity",
236:                                        exp);
237:                    }
238:                    return false;
239:                }
240:
241:            }
242:
243:            /*
244:             * This method is called when the existing connection is wrapped to another
245:             * pool.
246:             */
247:            private Connection getConnectionFromOtherPool(String owner)
248:                    throws ConnectionPoolException {
249:
250:                try {
251:                    synchronized (this ) {
252:                        if (config.getMaxConnections() == usedConnections) {
253:                            try {
254:                                debug.print("Hey the value is "
255:                                        + config.getConnectionWaitTimeOut());
256:                                wait(config.getConnectionWaitTimeOut());
257:                                if (config.getMaxConnections() == usedConnections) {
258:                                    throw new TimeOutException(
259:                                            "Timed-out while "
260:                                                    + "waiting for free connection");
261:                                }
262:                            } catch (InterruptedException ie) {
263:                            }
264:                        }
265:
266:                        Connection conn = connProvider.getConnection();
267:                        usedConnections++;
268:                        currentPoolSize++;
269:                        // Checking if the connection is still live and active
270:                        // if not get replace the old one with new one
271:                        if (checkIfValid(conn)) {
272:                            SmartConnection smt = new SmartConnection(conn,
273:                                    this , owner, config.isAutoClose());
274:                            connectionList.add(smt);
275:                            return smt;
276:                        } else {
277:                            boolean valid = false;
278:                            int i = 1;
279:                            while (!valid) {
280:                                conn = connProvider.getConnection();
281:                                valid = checkIfValid(conn);
282:                                i++;
283:                                if (i == 3 && !valid)
284:                                    throw new ConnectionPoolException(
285:                                            "Three consecutive cnnections failes the Validator Query org.smartlib.pool.test");
286:                            }
287:                            SmartConnection smt = new SmartConnection(conn,
288:                                    this , owner, config.isAutoClose());
289:                            connectionList.add(smt);
290:                            return smt;
291:                        }
292:                    }
293:                } catch (ConnectionPoolException cpe) {
294:                    throw cpe;
295:                } catch (Exception exp) {
296:                    throw new ConnectionPoolException(
297:                            "Error while getting connections from the Connection Loader Class",
298:                            exp);
299:                }
300:
301:            }
302:
303:            /**
304:             * This method returns a Connection from the  pool.
305:             * The owner of this connection is identified by <code>owner</code> .
306:             *
307:             * <b>Note: This method blocks if the pool size has reached it's
308:             * maximum size and no free connections are available
309:             * until a free connection is available</b>. The time period for which this
310:             * method blocks depends on the connection-wait-time-out specified in
311:             * the configuration file.
312:             *
313:             *
314:             * @param owner String identifying the owner.
315:             * @return Connection from the pool
316:             *
317:             * @exception ConnectionPoolException if there is any problem
318:             *		getting connection.
319:             */
320:            public Connection getConnection(String owner)
321:                    throws ConnectionPoolException {
322:
323:                // Check for external pooling
324:                if (connProvider != null)
325:                    return getConnectionFromOtherPool(owner);
326:
327:                Enumeration cons = connectionHash.keys();
328:                //debug.print("Getting Connection " + usedConnections);
329:                synchronized (connectionHash) {
330:                    // Checking if max-conn is less than used connection  , if not wait
331:                    if (config.getMaxConnections() == usedConnections) {
332:                        try {
333:                            //debug.print("Waiting for Connection " + usedConnections);
334:                            debug.print("Hey the value is "
335:                                    + config.getConnectionWaitTimeOut());
336:                            connectionHash.wait(config
337:                                    .getConnectionWaitTimeOut());
338:                            if (config.getMaxConnections() == usedConnections) {
339:                                throw new TimeOutException("Timed-out while "
340:                                        + "waiting for free connection");
341:                            }
342:
343:                        } catch (InterruptedException ie) {
344:                        }
345:                    }
346:
347:                    // Reached here indicates that free conn is available or
348:                    // currentpool size is less and thus new conn can be added to pool
349:                    while (cons.hasMoreElements()) {
350:                        // Checking if any unused connection is available
351:                        Connection con = (Connection) cons.nextElement();
352:                        Boolean b = (Boolean) connectionHash.get(con);
353:                        if (b == Boolean.TRUE) {
354:                            //Unused Connection is available
355:                            connectionHash.put(con, Boolean.FALSE);
356:                            usedConnections++;
357:                            debug.print("Hey After Incrementing conn "
358:                                    + usedConnections);
359:                            //debug.print("Connection Obtained " + usedConnections);
360:                            // Checking if the connection is still live and active
361:                            // if not get replace the old one with new one
362:                            if (checkIfValid(con)) {
363:                                SmartConnection smt = new SmartConnection(con,
364:                                        this , owner, config.isAutoClose());
365:                                connectionList.add(smt);
366:                                return smt;
367:                            } else {
368:                                boolean valid = false;
369:                                int failCounter = 1;
370:                                while (!valid) {
371:                                    connectionHash.remove(con);
372:                                    con = loadConnection();
373:                                    connectionHash.put(con, Boolean.FALSE);
374:                                    failCounter++;
375:                                    valid = checkIfValid(con);
376:                                    if (failCounter == 3 && !valid)
377:                                        throw new ConnectionPoolException(
378:                                                "Three consecutive connections failed the Validator Query org.smartlib.pool.test");
379:                                }
380:                                SmartConnection smt = new SmartConnection(con,
381:                                        this , owner, config.isAutoClose());
382:                                connectionList.add(smt);
383:                                return smt;
384:                            }
385:                        }
386:                    }
387:
388:                    // No Connection available hence increase the pool size
389:                    int increment = config.getIncrement();
390:                    Connection c = null;
391:                    SmartConnection smt = null;
392:                    for (int i = 0; i < increment
393:                            && i + currentPoolSize <= config
394:                                    .getMaxConnections(); i++) {
395:                        c = loadConnection();
396:                        boolean valid = checkIfValid(c);
397:                        int failCounter = 1;
398:                        while (!valid) {
399:                            c = loadConnection();
400:                            failCounter++;
401:                            valid = checkIfValid(c);
402:                            if (failCounter == 3 && !valid)
403:                                throw new ConnectionPoolException(
404:                                        "Three consecutive connections failed the Validator Query org.smartlib.pool.test");
405:                        }
406:                        if (i == 0) {
407:                            smt = new SmartConnection(c, this , owner, config
408:                                    .isAutoClose());
409:                            connectionHash.put(c, Boolean.FALSE);
410:                        } else
411:                            connectionHash.put(c, Boolean.TRUE);
412:                    }
413:
414:                    //debug.print("Connection Incremented " + usedConnections);
415:                    //debug.print("Pool Size" + currentPoolSize);
416:                    usedConnections++;
417:                    connectionList.add(smt);
418:                    return smt;
419:
420:                }
421:
422:            }
423:
424:            /**
425:             * This method releases the connection back to the pool.
426:             * @param ret connection to be released
427:             */
428:            public void returnConnection(Connection ret) {
429:
430:                if (connProvider != null) {
431:                    try {
432:                        synchronized (this ) {
433:                            Connection conn = ((SmartConnection) ret)
434:                                    .returnConnection();
435:                            returnConnectionToOtherPool(conn);
436:                            usedConnections--;
437:                            currentPoolSize--;
438:                            debug.print("Removed value is "
439:                                    + connectionList.removeElement(ret));
440:                            notifyAll();
441:                        }
442:                    } catch (Exception exp) {
443:                        // Error while returning
444:                        debug.print("Error " + exp);
445:                    }
446:                    return;
447:                }
448:
449:                Object tempRef = ret;
450:                SmartConnection smt = (SmartConnection) ret;
451:                ret = smt.returnConnection();
452:                Connection con;
453:                Enumeration cons = connectionHash.keys();
454:                synchronized (connectionHash) {
455:                    while (cons.hasMoreElements()) {
456:                        con = (Connection) cons.nextElement();
457:                        if (con == ret) {
458:                            connectionHash.put(con, Boolean.TRUE);
459:                            break;
460:                        }
461:                    }
462:                    debug.print("Connection Released " + usedConnections);
463:                    usedConnections--;
464:                    debug.print("Connection contains list "
465:                            + connectionList.contains(tempRef));
466:                    debug.print("Removed value is "
467:                            + connectionList.removeElement(tempRef));
468:
469:                    connectionHash.notifyAll();
470:                }
471:
472:            }
473:
474:            /**
475:             * This method adds a connection leak listener. The methods of
476:             * <code>cle</code> will be called when a leak is detected as per the
477:             * pool configuration.
478:             *
479:             * @param cle Class implementing ConnectionLeakListener interface.
480:             * @exception ConnectionPoolException if there is any problem
481:             *	 adding ConnectionLeakListener.
482:             */
483:            public void addConnectionLeakListener(ConnectionLeakListener cle)
484:                    throws ConnectionPoolException {
485:
486:                if (cle == null)
487:                    throw new IllegalArgumentException(
488:                            "ConnectionLeakListener cannot be null");
489:                debug.print("Added is " + cle);
490:                connectionListenerList.add(cle);
491:
492:            }
493:
494:            /**
495:             * This method removes a connection leak listener. <code>cle</code> will
496:             * not get any  further notifications.
497:             *
498:             * @param cle Class implementing ConnectionLeakListener interface.
499:             * @exception ConnectionPoolException If there is any problem
500:             *	 removing ConnectionLeakListener.
501:             */
502:            public void removeConnectionLeakListener(ConnectionLeakListener cle)
503:                    throws ConnectionPoolException {
504:
505:                if (cle == null)
506:                    throw new IllegalArgumentException(
507:                            "ConnectionLeakListener cannot be null");
508:                debug.print("Trying to remove " + cle);
509:                boolean found = connectionListenerList.remove(cle);
510:                if (!found)
511:                    throw new ConnectionPoolException("No Such Listener");
512:
513:            }
514:
515:            /**
516:             * This method releases excessive connections, i.e it actully closes
517:             * them.
518:             */
519:            public void releaseConnections() {
520:
521:                if (config.getMaxConnectionsForRelease() == -1)
522:                    return;
523:                if (config.getMaxConnectionsForRelease() < getNoOfFreeConnections()) {
524:                    int i = config.getIncrement();
525:                    synchronized (connectionHash) {
526:                        Enumeration cons = connectionHash.keys();
527:                        while (cons.hasMoreElements() && i > 0) {
528:                            Connection con = (Connection) cons.nextElement();
529:                            Boolean b = (Boolean) connectionHash.get(con);
530:                            if (b == Boolean.TRUE) {
531:                                connectionHash.remove(con);
532:                                try {
533:                                    con.close();
534:                                    i--;
535:                                    currentPoolSize = connectionHash.size();
536:                                    debug.print("Releasing conn" + con);
537:                                } catch (SQLException e) {
538:                                    debug.print("Error in closing connection"
539:                                            + e);
540:                                }
541:                            }
542:                        }
543:                    }
544:                }
545:
546:            }
547:
548:            public void shutDown() {
549:                if (logger.isDebugEnabled()) {
550:                    logger.debug("Shutting down connections for pool:" + name);
551:                }
552:                shutDown = true;
553:                Enumeration cons = connectionHash.keys();
554:                while (cons.hasMoreElements()) {
555:                    Connection con = (Connection) cons.nextElement();
556:                    try {
557:                        con.close();
558:                    } catch (Exception e) {
559:                        logger.warn(
560:                                "Exception occurred during connections close",
561:                                e);
562:                    }
563:                }
564:
565:            }
566:
567:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.