Source Code Cross Referenced for ProxyConnection.java in  » Database-JDBC-Connection-Pool » proxool » org » logicalcobwebs » proxool » 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 » proxool » org.logicalcobwebs.proxool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This software is released under a licence similar to the Apache Software Licence.
003:         * See org.logicalcobwebs.proxool.package.html for details.
004:         * The latest version is available at http://proxool.sourceforge.net
005:         */
006:        package org.logicalcobwebs.proxool;
007:
008:        import org.logicalcobwebs.concurrent.WriterPreferenceReadWriteLock;
009:        import org.apache.commons.logging.Log;
010:        import org.apache.commons.logging.LogFactory;
011:        import org.logicalcobwebs.proxool.util.FastArrayList;
012:
013:        import java.sql.Connection;
014:        import java.sql.SQLException;
015:        import java.sql.Statement;
016:        import java.util.Date;
017:        import java.util.Set;
018:        import java.util.HashSet;
019:        import java.util.List;
020:        import java.text.DecimalFormat;
021:
022:        /**
023:         * Manages a connection. This is wrapped up inside a...
024:         *
025:         * @version $Revision: 1.37 $, $Date: 2006/01/18 14:40:02 $
026:         * @author bill
027:         * @author $Author: billhorsman $ (current maintainer)
028:         * @since Proxool 0.10
029:         */
030:        public class ProxyConnection implements  ProxyConnectionIF {
031:
032:            static final int STATUS_FORCE = -1;
033:
034:            private WriterPreferenceReadWriteLock statusReadWriteLock = new WriterPreferenceReadWriteLock();
035:
036:            private static final Log LOG = LogFactory
037:                    .getLog(ProxyConnection.class);
038:
039:            private Connection connection;
040:
041:            private String delegateUrl;
042:
043:            private int mark;
044:
045:            private String reasonForMark;
046:
047:            private int status;
048:
049:            private long id;
050:
051:            private Date birthDate;
052:
053:            private long timeLastStartActive;
054:
055:            private long timeLastStopActive;
056:
057:            private ConnectionPool connectionPool;
058:
059:            private ConnectionPoolDefinitionIF definition;
060:
061:            private String requester;
062:
063:            private Set openStatements = new HashSet();
064:
065:            private DecimalFormat idFormat = new DecimalFormat("0000");
066:
067:            private List sqlCalls = new FastArrayList();
068:
069:            /**
070:             * Whether we have invoked a method that requires us to reset
071:             */
072:            private boolean needToReset = false;
073:
074:            /**
075:             *
076:             * @param connection the real connection that is used
077:             * @param id unique ID
078:             * @param delegateUrl
079:             * @param connectionPool the pool it is a member of
080:             * @param definition the definition that was used to build it (could possibly be different from
081:             * the one held in the connectionPool)
082:             * @param status {@link #STATUS_ACTIVE}, {@link #STATUS_AVAILABLE}, {@link #STATUS_FORCE}, {@link #STATUS_NULL}, or {@link #STATUS_OFFLINE}
083:             * @throws SQLException
084:             */
085:            protected ProxyConnection(Connection connection, long id,
086:                    String delegateUrl, ConnectionPool connectionPool,
087:                    ConnectionPoolDefinitionIF definition, int status)
088:                    throws SQLException {
089:                this .connection = connection;
090:                this .delegateUrl = delegateUrl;
091:                setId(id);
092:                this .connectionPool = connectionPool;
093:                this .definition = definition;
094:                setBirthTime(System.currentTimeMillis());
095:
096:                this .status = status;
097:                if (status == STATUS_ACTIVE) {
098:                    setTimeLastStartActive(System.currentTimeMillis());
099:                }
100:
101:                // We only need to call this for the first connection we make. But it returns really
102:                // quickly and we don't call it that often so we shouldn't worry.
103:                connectionPool.initialiseConnectionResetter(connection);
104:
105:                if (connection == null) {
106:                    throw new SQLException("Unable to create new connection");
107:                }
108:            }
109:
110:            /**
111:             * Whether the underlying connections are equal
112:             * @param obj the object (probably another connection) that we
113:             * are being compared to
114:             * @return whether they are the same
115:             */
116:            public boolean equals(Object obj) {
117:                if (obj != null) {
118:                    if (obj instanceof  ProxyConnection) {
119:                        return connection.hashCode() == ((ProxyConnection) obj)
120:                                .getConnection().hashCode();
121:                    } else if (obj instanceof  Connection) {
122:                        return connection.hashCode() == obj.hashCode();
123:                    } else {
124:                        return super .equals(obj);
125:                    }
126:                } else {
127:                    return false;
128:                }
129:            }
130:
131:            /**
132:             * Whether this connection is available. (When you close the connection
133:             * it doesn't really close, it just becomes available for others to use).
134:             * @return true if the connection is not active
135:             */
136:            public boolean isClosed() {
137:                return (getStatus() != STATUS_ACTIVE);
138:            }
139:
140:            /**
141:             * The subclass should call this to indicate that a change has been made to
142:             * the connection that might mean it needs to be reset (like setting autoCommit
143:             * to false or something). We don't reset unless this has been called to avoid
144:             * the overhead of unnecessary resetting.
145:             *
146:             * @param needToReset true if the connection might need resetting.
147:             */
148:            protected void setNeedToReset(boolean needToReset) {
149:                this .needToReset = needToReset;
150:            }
151:
152:            /**
153:             * The ConnectionPool that this connection belongs to
154:             * @return connectionPool
155:             */
156:            protected ConnectionPool getConnectionPool() {
157:                return connectionPool;
158:            }
159:
160:            /**
161:             * Get the definition that was used to create this connection
162:             * @return definition
163:             */
164:            public ConnectionPoolDefinitionIF getDefinition() {
165:                return definition;
166:            }
167:
168:            /**
169:             * By calling this we can keep track of any statements that are
170:             * left open when this connection is returned to the pool.
171:             * @param statement the statement that we have just opened/created.
172:             * @see #registerClosedStatement
173:             */
174:            protected void addOpenStatement(Statement statement) {
175:                openStatements.add(statement);
176:            }
177:
178:            /**
179:             * @see ProxyConnectionIF#registerClosedStatement
180:             */
181:            public void registerClosedStatement(Statement statement) {
182:                if (openStatements.contains(statement)) {
183:                    openStatements.remove(statement);
184:                } else {
185:                    connectionPool
186:                            .getLog()
187:                            .warn(
188:                                    connectionPool.displayStatistics()
189:                                            + " - #"
190:                                            + getId()
191:                                            + " registered a statement as closed which wasn't known to be open.");
192:                }
193:            }
194:
195:            /**
196:             * Close the connection for real
197:             * @throws java.sql.SQLException if anything goes wrong
198:             */
199:            public void reallyClose() throws SQLException {
200:                try {
201:                    connectionPool.registerRemovedConnection(getStatus());
202:                    // Clean up the actual connection
203:                    connection.close();
204:                } catch (Throwable t) {
205:                    connectionPool
206:                            .getLog()
207:                            .error(
208:                                    "#"
209:                                            + idFormat.format(getId())
210:                                            + " encountered errors during destruction: ",
211:                                    t);
212:                }
213:
214:            }
215:
216:            /**
217:             * @see ProxyConnectionIF#isReallyClosed
218:             */
219:            public boolean isReallyClosed() throws SQLException {
220:                if (connection == null) {
221:                    return true;
222:                } else {
223:                    return connection.isClosed();
224:                }
225:            }
226:
227:            /**
228:             * @see ProxyConnectionIF#close
229:             */
230:            public void close() throws SQLException {
231:                try {
232:                    boolean removed = false;
233:                    if (isMarkedForExpiry()) {
234:                        if (connectionPool.getLog().isDebugEnabled()) {
235:                            connectionPool
236:                                    .getLog()
237:                                    .debug(
238:                                            "Closing connection quickly (without reset) because it's marked for expiry anyway");
239:                        }
240:                    } else {
241:                        // Close any open statements, as specified in JDBC
242:                        Statement[] statements = (Statement[]) openStatements
243:                                .toArray(new Statement[openStatements.size()]);
244:                        for (int j = 0; j < statements.length; j++) {
245:                            Statement statement = statements[j];
246:                            statement.close();
247:                            if (connectionPool.getLog().isDebugEnabled()) {
248:                                connectionPool.getLog().debug(
249:                                        "Closing statement "
250:                                                + Integer.toHexString(statement
251:                                                        .hashCode())
252:                                                + " automatically");
253:                            }
254:                        }
255:                        openStatements.clear();
256:
257:                        if (needToReset) {
258:                            // This call should be as quick as possible. Should we consider only
259:                            // calling it if values have changed? The trouble with that is that it
260:                            // means keeping track when they change and that might be even
261:                            // slower
262:                            if (!connectionPool.resetConnection(connection, "#"
263:                                    + getId())) {
264:                                connectionPool.removeProxyConnection(this ,
265:                                        "it couldn't be reset", true, true);
266:                                removed = true;
267:                            }
268:                            needToReset = false;
269:                        }
270:                    }
271:                    // If we removed it above then putting it back will only cause a confusing log event later when
272:                    // it is unable to be changed from ACTIVE to AVAILABLE.
273:                    if (!removed) {
274:                        connectionPool.putConnection(this );
275:                    }
276:                } catch (Throwable t) {
277:                    connectionPool
278:                            .getLog()
279:                            .error(
280:                                    "#"
281:                                            + idFormat.format(getId())
282:                                            + " encountered errors during closure: ",
283:                                    t);
284:                }
285:
286:            }
287:
288:            /**
289:             * This gets called /just/ before a connection is served. You can use it to reset some of the attributes.
290:             * The lifecycle is: {@link #open()} then {@link #close()}
291:             */
292:            protected void open() {
293:                sqlCalls.clear();
294:            }
295:
296:            public int getMark() {
297:                return mark;
298:            }
299:
300:            public int getStatus() {
301:                return status;
302:            }
303:
304:            /**
305:             * @see ProxyConnectionIF#setStatus(int)
306:             */
307:            public boolean setStatus(int newStatus) {
308:                return setStatus(STATUS_FORCE, newStatus);
309:            }
310:
311:            /**
312:             * @see ProxyConnectionIF#setStatus(int, int)
313:             */
314:            public boolean setStatus(int oldStatus, int newStatus) {
315:                boolean success = false;
316:                try {
317:                    statusReadWriteLock.writeLock().acquire();
318:                    connectionPool.acquireConnectionStatusWriteLock();
319:                    if (this .status == oldStatus || oldStatus == STATUS_FORCE) {
320:                        connectionPool.changeStatus(this .status, newStatus);
321:                        this .status = newStatus;
322:                        success = true;
323:
324:                        if (newStatus == oldStatus) {
325:                            LOG
326:                                    .warn("Unexpected attempt to change status from "
327:                                            + oldStatus
328:                                            + " to "
329:                                            + newStatus
330:                                            + ". Why would you want to do that?");
331:                        } else if (newStatus == STATUS_ACTIVE) {
332:                            setTimeLastStartActive(System.currentTimeMillis());
333:                        } else if (oldStatus == STATUS_ACTIVE) {
334:                            setTimeLastStopActive(System.currentTimeMillis());
335:                        }
336:                    }
337:                } catch (InterruptedException e) {
338:                    LOG.error("Unable to acquire write lock for status");
339:                } finally {
340:                    connectionPool.releaseConnectionStatusWriteLock();
341:                    statusReadWriteLock.writeLock().release();
342:                }
343:                return success;
344:            }
345:
346:            public long getId() {
347:                return id;
348:            }
349:
350:            public void setId(long id) {
351:                this .id = id;
352:            }
353:
354:            /**
355:             * @see ConnectionInfoIF#getBirthTime
356:             */
357:            public long getBirthTime() {
358:                return birthDate.getTime();
359:            }
360:
361:            /**
362:             * @see ConnectionInfoIF#getBirthDate
363:             */
364:            public Date getBirthDate() {
365:                return birthDate;
366:            }
367:
368:            /**
369:             * @see ConnectionInfoIF#getAge
370:             */
371:            public long getAge() {
372:                return System.currentTimeMillis() - getBirthTime();
373:            }
374:
375:            /**
376:             * @see ConnectionInfoIF#getBirthTime
377:             */
378:            public void setBirthTime(long birthTime) {
379:                birthDate = new Date(birthTime);
380:            }
381:
382:            /**
383:             * @see ConnectionInfoIF#getTimeLastStartActive
384:             */
385:            public long getTimeLastStartActive() {
386:                return timeLastStartActive;
387:            }
388:
389:            /**
390:             * @see ConnectionInfoIF#getTimeLastStartActive
391:             */
392:            public void setTimeLastStartActive(long timeLastStartActive) {
393:                this .timeLastStartActive = timeLastStartActive;
394:                setTimeLastStopActive(0);
395:            }
396:
397:            /**
398:             * @see ConnectionInfoIF#getTimeLastStopActive
399:             */
400:            public long getTimeLastStopActive() {
401:                return timeLastStopActive;
402:            }
403:
404:            /**
405:             * @see ConnectionInfoIF#getTimeLastStopActive
406:             */
407:            public void setTimeLastStopActive(long timeLastStopActive) {
408:                this .timeLastStopActive = timeLastStopActive;
409:            }
410:
411:            /**
412:             * @see ConnectionInfoIF#getRequester
413:             */
414:            public String getRequester() {
415:                return requester;
416:            }
417:
418:            /**
419:             * @see ConnectionInfoIF#getRequester
420:             */
421:            public void setRequester(String requester) {
422:                this .requester = requester;
423:            }
424:
425:            /**
426:             * @see ProxyConnectionIF#isNull
427:             */
428:            public boolean isNull() {
429:                return getStatus() == STATUS_NULL;
430:            }
431:
432:            /**
433:             * @see ProxyConnectionIF#isAvailable
434:             */
435:            public boolean isAvailable() {
436:                return getStatus() == STATUS_AVAILABLE;
437:            }
438:
439:            /**
440:             * @see ProxyConnectionIF#isActive
441:             */
442:            public boolean isActive() {
443:                return getStatus() == STATUS_ACTIVE;
444:            }
445:
446:            /**
447:             * @see ProxyConnectionIF#isOffline
448:             */
449:            public boolean isOffline() {
450:                return getStatus() == STATUS_OFFLINE;
451:            }
452:
453:            /**
454:             * @see ProxyConnectionIF#markForExpiry
455:             */
456:            public void markForExpiry(String reason) {
457:                mark = MARK_FOR_EXPIRY;
458:                reasonForMark = reason;
459:            }
460:
461:            /**
462:             * @see ProxyConnectionIF#isMarkedForExpiry
463:             */
464:            public boolean isMarkedForExpiry() {
465:                return getMark() == MARK_FOR_EXPIRY;
466:            }
467:
468:            /**
469:             * @see ProxyConnectionIF#getReasonForMark
470:             */
471:            public String getReasonForMark() {
472:                return reasonForMark;
473:            }
474:
475:            /**
476:             * @see ProxyConnectionIF#getConnection
477:             */
478:            public Connection getConnection() {
479:                return connection;
480:            }
481:
482:            /**
483:             * @see Object#toString
484:             */
485:            public String toString() {
486:                return getId() + " is "
487:                        + ConnectionPool.getStatusDescription(getStatus());
488:            }
489:
490:            /**
491:             * @see ConnectionInfoIF#getDelegateUrl
492:             */
493:            public String getDelegateUrl() {
494:                return delegateUrl;
495:            }
496:
497:            /**
498:             * @see ConnectionInfoIF#getProxyHashcode
499:             */
500:            public String getProxyHashcode() {
501:                return Integer.toHexString(hashCode());
502:            }
503:
504:            /**
505:             * @see ConnectionInfoIF#getDelegateHashcode
506:             */
507:            public String getDelegateHashcode() {
508:                if (connection != null) {
509:                    return Integer.toHexString(connection.hashCode());
510:                } else {
511:                    return null;
512:                }
513:            }
514:
515:            /**
516:             * Compares using {@link #getId()}
517:             * @param o must be another {@link ConnectionInfoIF} implementation
518:             * @return the comparison
519:             * @see Comparable#compareTo(Object)
520:             */
521:            public int compareTo(Object o) {
522:                return new Long(((ConnectionInfoIF) o).getId())
523:                        .compareTo(new Long(getId()));
524:            }
525:
526:            public String[] getSqlCalls() {
527:                return (String[]) sqlCalls.toArray(new String[0]);
528:            }
529:
530:            public String getLastSqlCall() {
531:                if (sqlCalls != null && sqlCalls.size() > 0) {
532:                    return (String) sqlCalls.get(sqlCalls.size() - 1);
533:                } else {
534:                    return null;
535:                }
536:            }
537:
538:            public void addSqlCall(String sqlCall) {
539:                this.sqlCalls.add(sqlCall);
540:            }
541:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.