Source Code Cross Referenced for PooledDataSource.java in  » Database-ORM » XORM » org » xorm » datastore » sql » 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 » XORM » org.xorm.datastore.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:            $Header: /cvsroot/xorm/xorm/src/org/xorm/datastore/sql/PooledDataSource.java,v 1.7 2003/07/12 00:57:29 sbendar Exp $
003:
004:            This file is part of XORM.
005:
006:            XORM is free software; you can redistribute it and/or modify
007:            it under the terms of the GNU General Public License as published by
008:            the Free Software Foundation; either version 2 of the License, or
009:            (at your option) any later version.
010:
011:            XORM is distributed in the hope that it will be useful,
012:            but WITHOUT ANY WARRANTY; without even the implied warranty of
013:            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:            GNU General Public License for more details.
015:
016:            You should have received a copy of the GNU General Public License
017:            along with XORM; if not, write to the Free Software
018:            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:        package org.xorm.datastore.sql;
021:
022:        import java.util.Iterator;
023:        import java.util.Properties;
024:        import java.util.LinkedList;
025:        import java.util.logging.Logger;
026:        import java.util.logging.Level;
027:
028:        import java.io.PrintWriter;
029:
030:        import java.sql.Connection;
031:        import java.sql.Statement;
032:        import java.sql.SQLException;
033:        import java.sql.Driver;
034:
035:        import javax.sql.DataSource;
036:
037:        /**
038:         * Wraps a JDBC driver manager and provides a pooling of connections.
039:         *
040:         * @author Scott Bendar
041:         * @version $Revision: 1.7 $
042:         */
043:        public class PooledDataSource implements  DataSource {
044:
045:            private static final Logger logger = Logger
046:                    .getLogger("org.xorm.datastore.sql");
047:
048:            /**
049:             * Milliseconds to wait for a connection to become available
050:             * before waking up and logging the wait before waiting again.
051:             * This is overridden if the loginTimeout is less than this.
052:             */
053:            private static final int DEFAULT_TIMEOUT_MS = 5000;
054:
055:            private String connectionURL = null;
056:            private String driverName = null;
057:            private int minPool = 0;
058:            private int maxPool = 5;
059:            private int loginTimeout = 0;
060:            private boolean checkReturnedConnection = false;
061:            private long idleCheck = 0;
062:            private Integer isolationLevel;
063:            private String idleCheckSQL = null;
064:
065:            protected Properties props = new Properties();
066:            protected int connCount = 0;
067:
068:            protected Driver driver = null;
069:
070:            protected LinkedList availableConnections = new LinkedList();
071:
072:            /**
073:             * Initializes a new pooled data source
074:             */
075:            public PooledDataSource() {
076:            }
077:
078:            /**
079:             * Sets the user name to pass when making a db connection
080:             */
081:            public void setUser(String s) {
082:                props.setProperty("user", s);
083:            }
084:
085:            public String getUser() {
086:                return props.getProperty("user");
087:            }
088:
089:            /**
090:             * Sets the password to use when creating a db connection.  For
091:             * security reasons, there is no way to get the password.
092:             */
093:            public void setPassword(String s) {
094:                props.setProperty("password", s);
095:            }
096:
097:            /**
098:             * Set the URL used to connect to the DB
099:             */
100:            public void setConnectionUrl(String s) {
101:                connectionURL = s;
102:            }
103:
104:            public String getConnectionUrl() {
105:                return connectionURL;
106:            }
107:
108:            /**
109:             * Set the name of the driver to load when connecting to the DB
110:             */
111:            public void setDriverName(String s) {
112:                driverName = s;
113:            }
114:
115:            public String getDriverName() {
116:                return driverName;
117:            }
118:
119:            /**
120:             * The maximum number of connections created by the data source.
121:             * Once the max is exceeded callers must wait for a connection to
122:             * become available.
123:             */
124:            public int getMaxPool() {
125:                return maxPool;
126:            }
127:
128:            public void setMaxPool(int i) {
129:                if (i < 1) {
130:                    logger
131:                            .info("Max pool size is disabled, setting to max int.");
132:                    i = Integer.MAX_VALUE;
133:                }
134:                maxPool = i;
135:            }
136:
137:            /**
138:             * The minimum number of connections in the pool.  It will create
139:             * this number of connections when the pool is first initialized
140:             * and the pool will never shrink below this many connections.
141:             */
142:            public int getMinPool() {
143:                return minPool;
144:            }
145:
146:            public void setMinPool(int i) {
147:                minPool = i;
148:            }
149:
150:            public int getLoginTimeout() {
151:                return loginTimeout;
152:            }
153:
154:            /**
155:             * Sets the maximum time to wait in seconds for a connection
156:             * before throwing an exception.
157:             */
158:            public void setLoginTimeout(int timeout) {
159:                loginTimeout = timeout;
160:            }
161:
162:            /**
163:             * If set, instructs the connection to verify its valid when the
164:             * caller is done with the connection (calls close).  This is used
165:             * for debugging purposes only to help catch folks to return closed
166:             * connections to the pool.
167:             */
168:            public boolean getCheckReturnedConnection() {
169:                return checkReturnedConnection;
170:            }
171:
172:            /**
173:             * If set, instructs the connection to verify its valid when the
174:             * caller is done with the connection (calls close).  This is used
175:             * for debugging purposes only to help catch folks to return closed
176:             * connections to the pool.
177:             */
178:            public void setCheckReturnedConnection(boolean value) {
179:                checkReturnedConnection = value;
180:            }
181:
182:            /**
183:             * Gets the amount of time in milliseconds a connection has been
184:             * idle before the pool tests the connection to see if its still
185:             * valid.
186:             *
187:             * -1: Never check
188:             * 0: Always check
189:             * 
190:             */
191:            public long getIdleCheck() {
192:                return idleCheck;
193:            }
194:
195:            /**
196:             * Sets the amount of time in milliseconds a connection has been
197:             * idle before the pool tests the connection to see if its still
198:             * valid.
199:             *
200:             * -1: Never check
201:             * 0: Always check
202:             * 
203:             */
204:            public void setIdleCheck(long idle) {
205:                idleCheck = idle;
206:            }
207:
208:            /**
209:             * Gets a sql statement to be used to check a connection.  If not
210:             * specified, isConnectionClosed() is called instead.
211:             */
212:            public String getIdleCheckSQL() {
213:                return idleCheckSQL;
214:            }
215:
216:            /**
217:             * Sets a sql statement to be used to check a connection.  If not
218:             * specified, isConnectionClosed() is called instead.
219:             */
220:            public void setIdleCheckSQL(String sql) {
221:                idleCheckSQL = sql;
222:            }
223:
224:            /**
225:             * Sets the transaction isolation level.  If null, no specific
226:             * setting is made on a Connection instance; otherwise, the wrapped
227:             * value is used.
228:             */
229:            public void setIsolationLevel(Integer isolationLevel) {
230:                this .isolationLevel = isolationLevel;
231:            }
232:
233:            public Integer getIsolationLevel() {
234:                return isolationLevel;
235:            }
236:
237:            /**
238:             * Gets a DB connection, actually a wrapper that allows the
239:             * connection to be pooled.  The method first allocates a
240:             * connection from the available pool, if there are none available
241:             * it creates a new connection unless that would put it over the
242:             * max pool size, in which case it forces the caller to wait.
243:             *
244:             * If the data source was configured with a loginTimeout value
245:             * greater than 0, it will wait for loginTimeout seconds for a
246:             * connection.
247:             */
248:            public Connection getConnection() throws SQLException {
249:
250:                PooledConnection conn = null;
251:
252:                int timeSpent = 0;
253:
254:                // Don't wait forever, wake up and check things out periodically
255:                int waitTime = DEFAULT_TIMEOUT_MS;
256:
257:                // If there is a fixed time we are willing to wait, just wait that
258:                // long
259:                if (loginTimeout > 0)
260:                    waitTime = loginTimeout;
261:
262:                synchronized (availableConnections) {
263:
264:                    // Initialize the driver the first time its used
265:                    if (driver == null)
266:                        initDriver();
267:
268:                    while (loginTimeout == 0 || timeSpent < loginTimeout) {
269:
270:                        long startTime = System.currentTimeMillis();
271:
272:                        if (availableConnections.size() > 0) {
273:                            logger
274:                                    .fine("getConnection(): using available connection");
275:                            conn = (PooledConnection) availableConnections
276:                                    .removeFirst();
277:                            conn.setClosed(false);
278:                            try {
279:                                testConnection(conn);
280:                                return conn;
281:                            } catch (SQLException e) {
282:                                /*
283:                                 * If it fails the test, get rid of the connection
284:                                 * so we will try and allocate a new one before
285:                                 * returning a SQLException to the caller.
286:                                 */
287:                                logger
288:                                        .log(
289:                                                Level.SEVERE,
290:                                                "Connection failed test, dropping connection from pool!",
291:                                                e);
292:                                dropConnection(conn);
293:                            }
294:                        } else {
295:                            if (connCount < maxPool) {
296:                                logger
297:                                        .fine("getConnection(): creating new connection");
298:                                conn = createNewConnection();
299:                                return conn;
300:                            } else {
301:                                logger
302:                                        .fine("getConnection(): waiting for available connection");
303:                                try {
304:                                    availableConnections.wait(waitTime);
305:                                } catch (InterruptedException e) {
306:                                    logger
307:                                            .fine("getConnection(): wait interrupted!");
308:                                }
309:                                timeSpent += (int) (System.currentTimeMillis() - startTime);
310:                                logger
311:                                        .fine("getConnection(): wait timeout, wait total is "
312:                                                + timeSpent + " seconds");
313:                            }
314:                        }
315:                    }
316:                }
317:
318:                logger.warning("getConnection(): wait exceeded loginTimeout");
319:                throw new SQLException(
320:                        "getConnection(): wait exceeded loginTimeout");
321:            }
322:
323:            /**
324:             * This function is currently not implemented as it doesn't allow
325:             * us to use the connections in the pool.  The workaround is to
326:             * create a new data source with a different user and password.
327:             *
328:             * Should this just pass back an unpooled real connection?
329:             */
330:            public Connection getConnection(String userName, String password)
331:                    throws SQLException {
332:
333:                throw new SQLException(
334:                        "getConnection(user,pass) not supported, create a new data source with desired user and password");
335:
336:            }
337:
338:            /**
339:             * The PooledDataSource class uses JDK 1.4 logging and ignores the
340:             * log writer.
341:             */
342:            public PrintWriter getLogWriter() {
343:                return null;
344:            }
345:
346:            public void setLogWriter(PrintWriter logger) {
347:            }
348:
349:            /**
350:             * Initialize the driver and create the initial connections up to
351:             * the min pool size.
352:             */
353:            private void initDriver() throws SQLException {
354:
355:                if (driver != null)
356:                    return;
357:
358:                logger.finer("initDriver() -- Entry");
359:
360:                try {
361:                    Class driverClass = Class.forName(driverName);
362:                    driver = (Driver) driverClass.newInstance();
363:
364:                    // Create the minimum connections
365:                    while (connCount < minPool) {
366:                        availableConnections.add(createNewConnection());
367:                    }
368:
369:                } catch (Throwable t) {
370:                    throw new SQLException("initDriver: " + t);
371:                }
372:
373:            }
374:
375:            /**
376:             * Creats a new physical db connection and wraps it in our
377:             * PooledConnection
378:             */
379:            private PooledConnection createNewConnection() throws SQLException {
380:
381:                PooledConnection conn = null;
382:                if (driver != null) {
383:                    conn = new PooledConnection(this , driver.connect(
384:                            connectionURL, props));
385:                    if (isolationLevel != null) {
386:                        conn.setTransactionIsolation(isolationLevel.intValue());
387:                    }
388:                    connCount++;
389:                }
390:
391:                return conn;
392:            }
393:
394:            /**
395:             * Tests if the connection is still valid or not.
396:             */
397:            private void testConnection(PooledConnection conn)
398:                    throws SQLException {
399:                if (conn.hasReceivedException()
400:                        || (idleCheck >= 0 && (System.currentTimeMillis()
401:                                - conn.getLastUsedTime() > idleCheck))) {
402:
403:                    conn.clearReceivedException();
404:
405:                    if (!isConnectionValid(conn))
406:                        throw new SQLException(
407:                                "Connection is invalid, remove from pool.");
408:                }
409:            }
410:
411:            /**
412:             * Checks if a connection is active by running a SQL query specified
413:             * by IdleCheckSQL or by calling isClosed() if no sql statement has
414:             * been specified.
415:             */
416:            private boolean isConnectionValid(PooledConnection conn)
417:                    throws SQLException {
418:
419:                if (idleCheckSQL == null) {
420:                    logger.fine("Checking connection using isClosed");
421:                    return !conn.isConnectionClosed();
422:                } else {
423:                    logger
424:                            .fine("Checking connection with SQL: "
425:                                    + idleCheckSQL);
426:                    Statement statement = conn.createStatement();
427:
428:                    try {
429:                        statement.execute(idleCheckSQL);
430:                    } finally {
431:                        statement.close();
432:                    }
433:                    return true;
434:                }
435:            }
436:
437:            /**
438:             * Makes the connection available again.  This is called by the
439:             * PooledConnection class when the user chooses to close a
440:             * connection.
441:             */
442:            protected void makeAvailable(PooledConnection conn) {
443:                synchronized (availableConnections) {
444:                    availableConnections.add(conn);
445:                    logger.fine("makeAvailable(): available="
446:                            + availableConnections.size() + " total="
447:                            + connCount);
448:                    availableConnections.notify();
449:                }
450:            }
451:
452:            /** Releases all available connections. */
453:            // TODO: handle closure of connections that are currently leased
454:            public void close() {
455:                synchronized (availableConnections) {
456:                    Iterator i = availableConnections.iterator();
457:                    while (i.hasNext()) {
458:                        PooledConnection conn = (PooledConnection) i.next();
459:                        conn.closeConnection();
460:                        i.remove();
461:                        connCount--;
462:                    }
463:                }
464:            }
465:
466:            /** remove a connection from the pool */
467:            protected void dropConnection(PooledConnection conn) {
468:                synchronized (availableConnections) {
469:                    conn.closeConnection();
470:                    connCount--;
471:                }
472:            }
473:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.