Source Code Cross Referenced for DbConnection.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » database » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.database 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003:         * Distributed under the terms of either:
0004:         * - the common development and distribution license (CDDL), v1.0; or
0005:         * - the GNU Lesser General Public License, v2.1 or later
0006:         * $Id: DbConnection.java 3634 2007-01-08 21:42:24Z gbevin $
0007:         */
0008:        package com.uwyn.rife.database;
0009:
0010:        import com.uwyn.rife.database.exceptions.*;
0011:
0012:        import com.uwyn.rife.database.queries.Query;
0013:        import com.uwyn.rife.tools.ExceptionUtils;
0014:        import java.sql.Connection;
0015:        import java.sql.DatabaseMetaData;
0016:        import java.sql.PreparedStatement;
0017:        import java.sql.SQLException;
0018:        import java.sql.Statement;
0019:        import java.util.ArrayList;
0020:        import java.util.logging.Logger;
0021:
0022:        /**
0023:         * Represents one connection to a database. A connection has to be obtained by
0024:         * using the <code>getConnection</code> method on a <code>Datasource</code>
0025:         * instance. The resulting <code>DbConnection</code> instance can be used to
0026:         * obtain statement objects from and to manage transactions.
0027:         * <p>Statements are used to execute SQL queries either in a static or in a
0028:         * prepared fashion. This corresponds to the <code>DbStatement</code> and
0029:         * <code>DbPreparedStatement</code> classes. Look there for details about how
0030:         * to use them. A <code>DbConnection</code> keeps track of which statements
0031:         * have been openened and will automatically close them when database access
0032:         * errors occur or when the connection itself is closed.
0033:         * <p>Several statements can be executed as a whole through the use of
0034:         * transactions. Only if they all succeeded, the transaction should be
0035:         * committed and all the modifications will be preserved. Otherwise, the
0036:         * transaction should be rolled back, and the modifications will not be
0037:         * integrated into the general data storage. When a transaction has been
0038:         * started through the <code>beginTransaction()</code> method, it will be
0039:         * bound to the currently executing thread. Other threads will not be able to
0040:         * manipulate the transaction status and if they obtain and execute
0041:         * statements, they will be put in a wait state and woken up again after the
0042:         * transaction has finished.
0043:         * 
0044:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
0045:         * @version $Revision: 3634 $
0046:         * @see com.uwyn.rife.database.Datasource#getConnection()
0047:         * @see com.uwyn.rife.database.DbStatement
0048:         * @see com.uwyn.rife.database.DbPreparedStatement
0049:         * @since 1.0
0050:         */
0051:        public class DbConnection {
0052:            private static final int TRANSACTIONS_SUPPORT_UNKNOWN = -1;
0053:            private static final int TRANSACTIONS_UNSUPPORTED = 0;
0054:            private static final int TRANSACTIONS_SUPPORTED = 1;
0055:
0056:            private final Datasource mDatasource;
0057:            private Connection mConnection = null;
0058:            private ArrayList<DbStatement> mStatements = null;
0059:            private int mSupportsTransactions = TRANSACTIONS_SUPPORT_UNKNOWN;
0060:            private Thread mTransactionThread = null;
0061:
0062:            /**
0063:             * Creates a new <code>DbConnection</code> instance and binds it to a
0064:             * <code>Datasource</code> and a regular JDBC <code>Connection</code>.
0065:             * 
0066:             * @param connection the JDBC <code>Connection</code> that will be used
0067:             * @param datasource the <code>Datasource</code> this connection been
0068:             * obtained from
0069:             * @since 1.0
0070:             */
0071:            DbConnection(Connection connection, Datasource datasource) {
0072:                assert connection != null;
0073:                assert datasource != null;
0074:
0075:                mDatasource = datasource;
0076:                mConnection = connection;
0077:                mStatements = new ArrayList<DbStatement>();
0078:
0079:                assert mConnection != null;
0080:                assert mDatasource != null;
0081:                assert mStatements != null;
0082:                assert 0 == mStatements.size();
0083:            }
0084:
0085:            /**
0086:             * Retrieves the datasource this connection has been obtained from.
0087:             * 
0088:             * @return the <code>Datasource</code> instance this connection has been
0089:             * obtained from
0090:             * @since 1.0
0091:             */
0092:            public Datasource getDatasource() {
0093:                return mDatasource;
0094:            }
0095:
0096:            /**
0097:             * Releases all the resources that are being used by this connection. If
0098:             * the connection has been obtained from a pooled datasource, it will not
0099:             * be closed, but reused later. If the datasource isn't pooled, the
0100:             * connection itself will be closed as expected.
0101:             * <p>Any ongoing transactions will be automatically rolled-back.
0102:             * <p>All open statements will be closed and if a transaction is active,
0103:             * it will be automatically rolled back and unregistered.
0104:             * 
0105:             * @exception DatabaseException if a database access error occurs, or if
0106:             * an error occurred during the closing of an ongoing transaction, or if
0107:             * an error occurred during the closing of the opened statements, or if an
0108:             * error occurred during the closing of the underlying JDBC connection.
0109:             * @since 1.0
0110:             */
0111:            public void close() throws DatabaseException {
0112:                if (isClosed()) {
0113:                    synchronized (this ) {
0114:                        this .notifyAll();
0115:                    }
0116:                    return;
0117:                }
0118:
0119:                synchronized (this ) {
0120:                    if (hasTransactionThread()
0121:                            && !isTransactionValidForThread()) {
0122:                        return;
0123:                    }
0124:
0125:                    try {
0126:                        // only close the connection when no pool is active and not
0127:                        // inside a transaction
0128:                        if (!mDatasource.isPooled()
0129:                                && !(hasTransactionThread() && isTransactionValidForThread())) {
0130:                            try {
0131:                                try {
0132:                                    while (mStatements.size() > 0) {
0133:                                        mStatements.get(0).close();
0134:                                    }
0135:                                    mStatements = new ArrayList<DbStatement>();
0136:                                } finally {
0137:                                    try {
0138:                                        mConnection.close();
0139:                                    } catch (SQLException e) {
0140:                                        throw new ConnectionCloseErrorException(
0141:                                                mDatasource, e);
0142:                                    }
0143:                                }
0144:                            } finally {
0145:                                mConnection = null;
0146:                                mSupportsTransactions = TRANSACTIONS_SUPPORT_UNKNOWN;
0147:                            }
0148:                        }
0149:                    } finally {
0150:                        this .notifyAll();
0151:                    }
0152:                }
0153:            }
0154:
0155:            /**
0156:             * Indicates whether this <code>DbConnection</code> instance has been
0157:             * cleaned up or not.
0158:             * 
0159:             * @return <code>true</code> if it has been cleaned up; or
0160:             * <p><code>false</code> otherwise.
0161:             */
0162:            boolean isCleanedUp() {
0163:                return null == mConnection;
0164:            }
0165:
0166:            /**
0167:             * This method is used to check if this <code>DbConnection</code> instance
0168:             * has been cleaned up before using the underlying JDBC connection.
0169:             * 
0170:             * @exception SQLException when it has been cleaned up.
0171:             */
0172:            void detectCleanup() throws SQLException {
0173:                if (isCleanedUp()) {
0174:                    throw new SQLException("The connection is closed.");
0175:                }
0176:            }
0177:
0178:            /**
0179:             * Cleans up all the resources that are used by this
0180:             * <code>DbConnection</code> instance. This is mainly used to correctly
0181:             * clean up in case of errors during execution.
0182:             * 
0183:             * @exception DatabaseException if an error occurred during the closing of
0184:             * an ongoing transaction, or if an error occurred during the closing of
0185:             * the opened statements,
0186:             * @since 1.0
0187:             */
0188:            void cleanup() throws DatabaseException {
0189:                Thread transaction_thread = null;
0190:                // unregister a transaction thread
0191:                if (mTransactionThread != null) {
0192:                    transaction_thread = mTransactionThread;
0193:                    mTransactionThread = null;
0194:                }
0195:
0196:                try {
0197:                    DbStatement statement = null;
0198:
0199:                    // close all active statements
0200:                    synchronized (this ) {
0201:                        while (mStatements.size() > 0) {
0202:                            statement = mStatements.get(0);
0203:                            statement.close();
0204:                            try {
0205:                                statement.cancel();
0206:                            } catch (DatabaseException e) {
0207:                                // don't do anything since some DBs don't correct support statement cancelling
0208:                            }
0209:                        }
0210:                        mStatements = new ArrayList<DbStatement>();
0211:                    }
0212:
0213:                    // reset the connect state
0214:                    if (mConnection != null) {
0215:                        // rollback an ongoing transaction
0216:                        try {
0217:                            mConnection.rollback();
0218:                            mConnection.setAutoCommit(true);
0219:                        } catch (SQLException e) {
0220:                        }
0221:
0222:                        // close the JDBC connection
0223:                        try {
0224:                            mConnection.close();
0225:                        } catch (SQLException e) {
0226:                        }
0227:                    }
0228:                    mConnection = null;
0229:                    mSupportsTransactions = TRANSACTIONS_SUPPORT_UNKNOWN;
0230:                } finally {
0231:                    if (transaction_thread != null) {
0232:                        mDatasource.getPool().unregisterThreadConnection(
0233:                                transaction_thread);
0234:                    }
0235:                }
0236:            }
0237:
0238:            /**
0239:             * Performs the cleanup logic in case an exception is thrown during
0240:             * execution. If the connection is part of a pooled datasource, all
0241:             * connections in the pool will be closed and the whole pool will be setup
0242:             * cleanly again. If the connection isn't pooled, it will be cleaned up
0243:             * properly.
0244:             * 
0245:             * @exception DatabaseException when an error occurs during the cleanup of
0246:             * the connection, or when an error occurs when the pool is set up again.
0247:             */
0248:            void handleException() throws DatabaseException {
0249:                if (!mDatasource.isPooled()) {
0250:                    synchronized (mDatasource) {
0251:                        synchronized (this ) {
0252:                            // cleanup the connection resources
0253:                            cleanup();
0254:                            this .notifyAll();
0255:                        }
0256:                    }
0257:                } else {
0258:                    // recreate all the pooled connections
0259:                    mDatasource.getPool().recreateConnection(this );
0260:                }
0261:            }
0262:
0263:            /**
0264:             * Creates a new <code>DbStatement</code> instance for this connection. It
0265:             * will be registered and automatically closed when this
0266:             * <code>DbConnection</code> cleans up. It is recommended though to
0267:             * manually close the statement when it's not needed anymore for sensible
0268:             * resource preservation.
0269:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0270:             * automatically closed and if it's part of a pool, all the other
0271:             * connections are closed too and the pool is set up again. Also, any
0272:             * ongoing transaction will be rolled-back automatically.
0273:             * 
0274:             * @return a new <code>DbStatement</code> instance
0275:             * @exception DatabaseException when an exception has occurred during the
0276:             * creation of the <code>DbStatement</code> instance
0277:             * @see com.uwyn.rife.database.DbStatement
0278:             * @see #getPreparedStatement(String)
0279:             * @see #getPreparedStatement(Query)
0280:             * @since 1.0
0281:             */
0282:            public DbStatement createStatement() throws DatabaseException {
0283:                try {
0284:                    detectCleanup();
0285:
0286:                    Statement statement = mConnection.createStatement();
0287:
0288:                    synchronized (this ) {
0289:                        DbStatement db_statement = new DbStatement(this ,
0290:                                statement);
0291:                        mStatements.add(db_statement);
0292:
0293:                        return db_statement;
0294:                    }
0295:                } catch (SQLException e) {
0296:                    handleException();
0297:                    throw new StatementCreationErrorException(mDatasource, e);
0298:                }
0299:            }
0300:
0301:            /**
0302:             * Creates a new <code>DbStatement</code> instance for this connection with
0303:             * the given type and concurrency. It
0304:             * will be registered and automatically closed when this
0305:             * <code>DbConnection</code> cleans up. It is recommended though to
0306:             * manually close the statement when it's not needed anymore for sensible
0307:             * resource preservation.
0308:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0309:             * automatically closed and if it's part of a pool, all the other
0310:             * connections are closed too and the pool is set up again. Also, any
0311:             * ongoing transaction will be rolled-back automatically.
0312:             * 
0313:             * @param resultSetType a result set type; one of ResultSet.TYPE_FORWARD_ONLY,
0314:             * ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
0315:             * @param resultSetConcurrency a concurrency type; one of
0316:             * ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE 
0317:             * @return a new <code>DbStatement</code> instance
0318:             * @exception DatabaseException when an exception has occurred during the
0319:             * creation of the <code>DbStatement</code> instance
0320:             * @see com.uwyn.rife.database.DbStatement
0321:             * @see #getPreparedStatement(String)
0322:             * @see #getPreparedStatement(Query)
0323:             * @since 1.0
0324:             */
0325:            public DbStatement createStatement(int resultSetType,
0326:                    int resultSetConcurrency) throws DatabaseException {
0327:                try {
0328:                    detectCleanup();
0329:
0330:                    Statement statement = mConnection.createStatement(
0331:                            resultSetType, resultSetConcurrency);
0332:
0333:                    synchronized (this ) {
0334:                        DbStatement db_statement = new DbStatement(this ,
0335:                                statement);
0336:                        mStatements.add(db_statement);
0337:
0338:                        return db_statement;
0339:                    }
0340:                } catch (SQLException e) {
0341:                    handleException();
0342:                    throw new StatementCreationErrorException(mDatasource, e);
0343:                }
0344:            }
0345:
0346:            /**
0347:             * Creates a new <code>DbStatement</code> instance for this connection with
0348:             * the given type, concurrency, and holdability.. It
0349:             * will be registered and automatically closed when this
0350:             * <code>DbConnection</code> cleans up. It is recommended though to
0351:             * manually close the statement when it's not needed anymore for sensible
0352:             * resource preservation.
0353:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0354:             * automatically closed and if it's part of a pool, all the other
0355:             * connections are closed too and the pool is set up again. Also, any
0356:             * ongoing transaction will be rolled-back automatically.
0357:             * 
0358:             * @param resultSetType a result set type; one of ResultSet.TYPE_FORWARD_ONLY,
0359:             * ResultSet.TYPE_SCROLL_INSENSITIVE, or ResultSet.TYPE_SCROLL_SENSITIVE
0360:             * @param resultSetConcurrency a concurrency type; one of
0361:             * ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE 
0362:             * @param resultSetHoldability one of the following ResultSet constants:
0363:             * ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT 
0364:             * @return a new <code>DbStatement</code> instance
0365:             * @exception DatabaseException when an exception has occurred during the
0366:             * creation of the <code>DbStatement</code> instance
0367:             * @see com.uwyn.rife.database.DbStatement
0368:             * @see #getPreparedStatement(String)
0369:             * @see #getPreparedStatement(Query)
0370:             * @since 1.0
0371:             */
0372:            public DbStatement createStatement(int resultSetType,
0373:                    int resultSetConcurrency, int resultSetHoldability)
0374:                    throws DatabaseException {
0375:                try {
0376:                    detectCleanup();
0377:
0378:                    Statement statement = mConnection.createStatement(
0379:                            resultSetType, resultSetConcurrency,
0380:                            resultSetHoldability);
0381:
0382:                    synchronized (this ) {
0383:                        DbStatement db_statement = new DbStatement(this ,
0384:                                statement);
0385:                        mStatements.add(db_statement);
0386:
0387:                        return db_statement;
0388:                    }
0389:                } catch (SQLException e) {
0390:                    handleException();
0391:                    throw new StatementCreationErrorException(mDatasource, e);
0392:                }
0393:            }
0394:
0395:            /**
0396:             * Creates a new <code>DbPreparedStatement</code> instance for this
0397:             * connection from a regular SQL query string. Since the statement is
0398:             * created from a <code>String</code> and not a
0399:             * <code>ParametrizedQuery</code> instance, information is lacking to be
0400:             * able to fully use the features of the resulting
0401:             * <code>DbPreparedStatement</code> instance. It's recommended to use the
0402:             * {@link #getPreparedStatement(Query)} method instead if this is
0403:             * possible.
0404:             * <p>The new statement will be registered and automatically closed when
0405:             * this <code>DbConnection</code> cleans up. It is recommended though to
0406:             * manually close the statement when it's not needed anymore for sensible
0407:             * resource preservation.
0408:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0409:             * automatically closed and if it's part of a pool, all the other
0410:             * connections are closed too and the pool is set up again. Also, any
0411:             * ongoing transaction will be rolled-back automatically.
0412:             * 
0413:             * @param sql a <code>String</code> instance with the SQL that is used to
0414:             * set up the prepared statement
0415:             * @return a new <code>DbPreparedStatement</code> instance
0416:             * @exception DatabaseException when an exception has occurred during the
0417:             * creation of the <code>DbPreparedStatement</code> instance
0418:             * @see com.uwyn.rife.database.DbPreparedStatement
0419:             * @see #createStatement()
0420:             * @see #getPreparedStatement(Query)
0421:             * @since 1.0
0422:             */
0423:            public DbPreparedStatement getPreparedStatement(String sql)
0424:                    throws DatabaseException {
0425:                if (null == sql)
0426:                    throw new IllegalArgumentException("sql can't be null.");
0427:                if (0 == sql.length())
0428:                    throw new IllegalArgumentException("sql can't be empty.");
0429:
0430:                try {
0431:                    detectCleanup();
0432:
0433:                    PreparedStatement prepared_statement = mConnection
0434:                            .prepareStatement(sql);
0435:
0436:                    synchronized (this ) {
0437:                        DbPreparedStatement db_prepared_statement = new DbPreparedStatement(
0438:                                this , sql, prepared_statement);
0439:                        mStatements.add(db_prepared_statement);
0440:
0441:                        return db_prepared_statement;
0442:                    }
0443:                } catch (SQLException e) {
0444:                    handleException();
0445:                    throw new PreparedStatementCreationErrorException(
0446:                            mDatasource, e);
0447:                }
0448:            }
0449:
0450:            /**
0451:             * Creates a new <code>DbPreparedStatement</code> instance for this
0452:             * connection from a <code>Query</code> instance that has the capability
0453:             * to retrieve auto-generated keys. The given constant tells the driver
0454:             * whether it should make auto-generated keys available for retrieval.
0455:             * This parameter is ignored if the SQL statement is not an INSERT
0456:             * statement.
0457:             * <p>Since the statement is created from a <code>String</code> and not a
0458:             * <code>ParametrizedQuery</code> instance, information is lacking to be
0459:             * able to fully use the features of the resulting
0460:             * <code>DbPreparedStatement</code> instance. It's recommended to use the
0461:             * {@link #getPreparedStatement(Query)} method instead if this is
0462:             * possible.
0463:             * <p>The new statement will be registered and automatically closed when
0464:             * this <code>DbConnection</code> cleans up. It is recommended though to
0465:             * manually close the statement when it's not needed anymore for sensible
0466:             * resource preservation.
0467:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0468:             * automatically closed and if it's part of a pool, all the other
0469:             * connections are closed too and the pool is set up again. Also, any
0470:             * ongoing transaction will be rolled-back automatically.
0471:             * 
0472:             * @param sql a <code>String</code> instance with the SQL that is used to
0473:             * set up the prepared statement
0474:             * @param autoGeneratedKeys a flag indicating whether auto-generated keys
0475:             * should be returned; one of <code>Statement.RETURN_GENERATED_KEYS</code>
0476:             * or <code>Statement.NO_GENERATED_KEYS</code>
0477:             * @return a new <code>DbPreparedStatement</code> instance
0478:             * @exception DatabaseException when an exception has occurred during the
0479:             * creation of the <code>DbPreparedStatement</code> instance
0480:             * @see com.uwyn.rife.database.DbPreparedStatement
0481:             * @see #createStatement()
0482:             * @see #getPreparedStatement(Query)
0483:             * @since 1.0
0484:             */
0485:            public DbPreparedStatement getPreparedStatement(String sql,
0486:                    int autoGeneratedKeys) throws DatabaseException {
0487:                if (null == sql)
0488:                    throw new IllegalArgumentException("sql can't be null.");
0489:                if (0 == sql.length())
0490:                    throw new IllegalArgumentException("sql can't be empty.");
0491:
0492:                try {
0493:                    detectCleanup();
0494:
0495:                    PreparedStatement prepared_statement = mConnection
0496:                            .prepareStatement(sql, autoGeneratedKeys);
0497:
0498:                    synchronized (this ) {
0499:                        DbPreparedStatement db_prepared_statement = new DbPreparedStatement(
0500:                                this , sql, prepared_statement);
0501:                        mStatements.add(db_prepared_statement);
0502:
0503:                        return db_prepared_statement;
0504:                    }
0505:                } catch (SQLException e) {
0506:                    handleException();
0507:                    throw new PreparedStatementCreationErrorException(
0508:                            mDatasource, e);
0509:                }
0510:            }
0511:
0512:            /**
0513:             * Creates a new <code>DbPreparedStatement</code> instance for this
0514:             * connection from a <code>Query</code> instance. Thanks to the additional
0515:             * meta-data that's stored in a <code>Query</code> object, it's possible
0516:             * to use the additional features that the
0517:             * <code>DbPreparedStatement</code> provides on top of regular JDBC
0518:             * methods.
0519:             * <p>The new statement will be registered and automatically closed when
0520:             * this <code>DbConnection</code> cleans up. It is recommended though to
0521:             * manually close the statement when it's not needed anymore for sensible
0522:             * resource preservation.
0523:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0524:             * automatically closed and if it's part of a pool, all the other
0525:             * connections are closed too and the pool is set up again. Also, any
0526:             * ongoing transaction will be rolled-back automatically.
0527:             * 
0528:             * @param query a <code>Query</code> instance that is used to set up the
0529:             * prepared statement
0530:             * @return a new <code>DbPreparedStatement</code> instance
0531:             * @exception DatabaseException when an exception has occurred during the
0532:             * creation of the <code>DbPreparedStatement</code> instance
0533:             * @see com.uwyn.rife.database.DbPreparedStatement
0534:             * @see #createStatement()
0535:             * @see #getPreparedStatement(String)
0536:             * @since 1.0
0537:             */
0538:            public DbPreparedStatement getPreparedStatement(Query query)
0539:                    throws DatabaseException {
0540:                if (null == query)
0541:                    throw new IllegalArgumentException("query can't be null.");
0542:                if (null == query.getSql())
0543:                    throw new IllegalArgumentException("query can't be empty.");
0544:
0545:                try {
0546:                    detectCleanup();
0547:
0548:                    String sql = query.getSql();
0549:                    PreparedStatement prepared_statement = mConnection
0550:                            .prepareStatement(sql);
0551:
0552:                    synchronized (this ) {
0553:                        DbPreparedStatement db_prepared_statement = new DbPreparedStatement(
0554:                                this , query, prepared_statement);
0555:                        mStatements.add(db_prepared_statement);
0556:
0557:                        return db_prepared_statement;
0558:                    }
0559:                } catch (SQLException e) {
0560:                    handleException();
0561:                    throw new PreparedStatementCreationErrorException(
0562:                            mDatasource, e);
0563:                }
0564:            }
0565:
0566:            /**
0567:             * Creates a new <code>DbPreparedStatement</code> instance for this
0568:             * connection from a <code>Query</code> instance that has the capability
0569:             * to retrieve auto-generated keys. The given constant tells the driver
0570:             * whether it should make auto-generated keys available for retrieval.
0571:             * This parameter is ignored if the SQL statement is not an INSERT
0572:             * statement.
0573:             * <p>Thanks to the additional meta-data that's stored in a
0574:             * <code>Query</code> object, it's possible to use the additional features
0575:             * that the <code>DbPreparedStatement</code> provides on top of regular
0576:             * JDBC methods.
0577:             * <p>The new statement will be registered and automatically closed when
0578:             * this <code>DbConnection</code> cleans up. It is recommended though to
0579:             * manually close the statement when it's not needed anymore for sensible
0580:             * resource preservation.
0581:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0582:             * automatically closed and if it's part of a pool, all the other
0583:             * connections are closed too and the pool is set up again. Also, any
0584:             * ongoing transaction will be rolled-back automatically.
0585:             * 
0586:             * @param query a <code>Query</code> instance that is used to set up the
0587:             * prepared statement
0588:             * @param autoGeneratedKeys a flag indicating whether auto-generated keys
0589:             * should be returned; one of <code>Statement.RETURN_GENERATED_KEYS</code>
0590:             * or <code>Statement.NO_GENERATED_KEYS</code>
0591:             * @return a new <code>DbPreparedStatement</code> instance
0592:             * @exception DatabaseException when an exception has occurred during the
0593:             * creation of the <code>DbPreparedStatement</code> instance
0594:             * @see com.uwyn.rife.database.DbPreparedStatement
0595:             * @see #createStatement()
0596:             * @see #getPreparedStatement(String)
0597:             * @since 1.0
0598:             */
0599:            public DbPreparedStatement getPreparedStatement(Query query,
0600:                    int autoGeneratedKeys) throws DatabaseException {
0601:                if (null == query)
0602:                    throw new IllegalArgumentException("query can't be null.");
0603:                if (null == query.getSql())
0604:                    throw new IllegalArgumentException("query can't be empty.");
0605:
0606:                try {
0607:                    detectCleanup();
0608:
0609:                    String sql = query.getSql();
0610:                    PreparedStatement prepared_statement = mConnection
0611:                            .prepareStatement(sql, autoGeneratedKeys);
0612:
0613:                    synchronized (this ) {
0614:                        DbPreparedStatement db_prepared_statement = new DbPreparedStatement(
0615:                                this , query, prepared_statement);
0616:                        mStatements.add(db_prepared_statement);
0617:
0618:                        return db_prepared_statement;
0619:                    }
0620:                } catch (SQLException e) {
0621:                    handleException();
0622:                    throw new PreparedStatementCreationErrorException(
0623:                            mDatasource, e);
0624:                }
0625:            }
0626:
0627:            /**
0628:             * Creates a new <code>DbPreparedStatement</code> instance for this
0629:             * connection from a <code>Query</code> instance that will generate
0630:             * <code>ResultSet</code> objects with the given type, concurrency,
0631:             * and holdability.
0632:             * <p>
0633:             * This method is the same as the <code>getPreparedStatement</code> method
0634:             * above, but it allows the default result set
0635:             * type, concurrency, and holdability to be overridden.
0636:             * <p>Thanks to the additional meta-data that's stored in a
0637:             * <code>Query</code> object, it's possible to use the additional features
0638:             * that the <code>DbPreparedStatement</code> provides on top of regular
0639:             * JDBC methods.
0640:             * <p>The new statement will be registered and automatically closed when
0641:             * this <code>DbConnection</code> cleans up. It is recommended though to
0642:             * manually close the statement when it's not needed anymore for sensible
0643:             * resource preservation.
0644:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0645:             * automatically closed and if it's part of a pool, all the other
0646:             * connections are closed too and the pool is set up again. Also, any
0647:             * ongoing transaction will be rolled-back automatically.
0648:             * 
0649:             * @param query a <code>Query</code> instance that is used to set up the
0650:             * prepared statement
0651:             * @param resultSetType one of the following <code>ResultSet</code> 
0652:             *        constants:
0653:             *         <code>ResultSet.TYPE_FORWARD_ONLY</code>, 
0654:             *         <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
0655:             *         <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
0656:             * @param resultSetConcurrency one of the following <code>ResultSet</code> 
0657:             *        constants:
0658:             *         <code>ResultSet.CONCUR_READ_ONLY</code> or
0659:             *         <code>ResultSet.CONCUR_UPDATABLE</code>
0660:             * @param resultSetHoldability one of the following <code>ResultSet</code> 
0661:             *        constants:
0662:             *         <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
0663:             *         <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
0664:             * @return a new <code>DbPreparedStatement</code> instance, that will generate
0665:             *         <code>ResultSet</code> objects with the given type,
0666:             *         concurrency, and holdability
0667:             * @exception DatabaseException when an exception has occurred during the
0668:             * creation of the <code>DbPreparedStatement</code> instance
0669:             * @see com.uwyn.rife.database.DbPreparedStatement
0670:             * @see #createStatement()
0671:             * @see #getPreparedStatement(String)
0672:             * @since 1.2
0673:             */
0674:            public DbPreparedStatement getPreparedStatement(Query query,
0675:                    int resultSetType, int resultSetConcurrency,
0676:                    int resultSetHoldability) throws DatabaseException {
0677:                if (null == query)
0678:                    throw new IllegalArgumentException("query can't be null.");
0679:                if (null == query.getSql())
0680:                    throw new IllegalArgumentException("query can't be empty.");
0681:
0682:                try {
0683:                    detectCleanup();
0684:
0685:                    String sql = query.getSql();
0686:                    PreparedStatement prepared_statement = mConnection
0687:                            .prepareStatement(sql, resultSetType,
0688:                                    resultSetConcurrency, resultSetHoldability);
0689:
0690:                    synchronized (this ) {
0691:                        DbPreparedStatement db_prepared_statement = new DbPreparedStatement(
0692:                                this , query, prepared_statement);
0693:                        mStatements.add(db_prepared_statement);
0694:
0695:                        return db_prepared_statement;
0696:                    }
0697:                } catch (SQLException e) {
0698:                    handleException();
0699:                    throw new PreparedStatementCreationErrorException(
0700:                            mDatasource, e);
0701:                }
0702:            }
0703:
0704:            /**
0705:             * Removes a <code>DbStatement</code> instance from the collection of
0706:             * managed statements. If the statement is not present, no error or
0707:             * exception is thrown.
0708:             * 
0709:             * @param statement the <code>DbStatement</code> that has to be removed.
0710:             * @since 1.0
0711:             */
0712:            void releaseStatement(DbStatement statement) {
0713:                synchronized (this ) {
0714:                    mStatements.remove(statement);
0715:                }
0716:            }
0717:
0718:            /**
0719:             * Indicates whether the <code>Datasource</code> of this
0720:             * <code>DbConnection</code> supports transactions or not.
0721:             * <p>This information is only retrieved once and cached for the rest of
0722:             * the lifetime of this connection.
0723:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0724:             * automatically closed and if it's part of a pool, all the other
0725:             * connections are closed too and the pool is set up again. Also, any
0726:             * ongoing transaction will be rolled-back automatically.
0727:             * 
0728:             * @return <code>true</code> if the <code>Datasource</code> supports
0729:             * transactions; or
0730:             * <p><code>false</code> if the <code>Datasource</code> doesn't support
0731:             * transactions.
0732:             * @exception DatabaseException when an error occurred during the
0733:             * verification of the transaction support
0734:             * @see #beginTransaction()
0735:             * @see #commit()
0736:             * @see #rollback()
0737:             * @see #isFree()
0738:             * @see #isTransactionValidForThread()
0739:             * @since 1.0
0740:             */
0741:            public boolean supportsTransactions() throws DatabaseException {
0742:                try {
0743:                    synchronized (this ) {
0744:                        detectCleanup();
0745:
0746:                        if (TRANSACTIONS_SUPPORT_UNKNOWN == mSupportsTransactions) {
0747:                            if (mConnection.getMetaData()
0748:                                    .supportsTransactions()) {
0749:                                mSupportsTransactions = TRANSACTIONS_SUPPORTED;
0750:                            } else {
0751:                                mSupportsTransactions = TRANSACTIONS_UNSUPPORTED;
0752:                            }
0753:                        }
0754:
0755:                        return TRANSACTIONS_SUPPORTED == mSupportsTransactions;
0756:
0757:                    }
0758:                } catch (SQLException e) {
0759:                    handleException();
0760:                    throw new TransactionSupportCheckErrorException(
0761:                            mDatasource, e);
0762:                }
0763:            }
0764:
0765:            /**
0766:             * <p><strong>Warning:</strong> only use the raw transaction methods if
0767:             * you really know what you're doing. It's almost always better to use the
0768:             * {@link DbQueryManager#inTransaction(DbTransactionUser) inTransaction}
0769:             * method of the <code>DbQueryManager</code> class instead.
0770:             * <p>Starts a new transaction if the <code>Datasource</code> supports it.
0771:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0772:             * automatically closed and if it's part of a pool, all the other
0773:             * connections are closed too and the pool is set up again. Also, any
0774:             * ongoing transaction will be rolled-back automatically.
0775:             * 
0776:             * @return <code>true</code> if the transaction was successfully started;
0777:             * or
0778:             * <p><code>false</code> if the <code>Datasource</code> doesn't support
0779:             * transactions, or if a transaction is already active on this
0780:             * <code>DbConnection</code>.
0781:             * @exception DatabaseException when an error occurred during the creation
0782:             * of the new transaction, or when the active transaction has timed-out.
0783:             * @see DbQueryManager#inTransaction(DbTransactionUser)
0784:             * @see #supportsTransactions()
0785:             * @see #commit()
0786:             * @see #rollback()
0787:             * @see #isFree()
0788:             * @see #isTransactionValidForThread()
0789:             * @since 1.0
0790:             */
0791:            public boolean beginTransaction() throws DatabaseException {
0792:                // if the datasource doesn't support transactions,
0793:                // don't start any
0794:                if (!supportsTransactions()) {
0795:                    return false;
0796:                }
0797:
0798:                synchronized (this ) {
0799:                    // check if a thread has already got a hold of this connection
0800:                    if (hasTransactionThread()) {
0801:                        // if it's still active, it's impossible to begin a new
0802:                        // transaction
0803:                        return false;
0804:                    }
0805:
0806:                    // setup the new transaction
0807:                    mTransactionThread = Thread.currentThread();
0808:                }
0809:
0810:                try {
0811:                    detectCleanup();
0812:
0813:                    mConnection.setAutoCommit(false);
0814:                } catch (SQLException e) {
0815:
0816:                    if (mTransactionThread != null) {
0817:                        mTransactionThread = null;
0818:                    }
0819:                    handleException();
0820:                    throw new TransactionBeginErrorException(mDatasource, e);
0821:                }
0822:
0823:                mDatasource.getPool().registerThreadConnection(
0824:                        mTransactionThread, this );
0825:
0826:                return true;
0827:            }
0828:
0829:            /**
0830:             * <p><strong>Warning:</strong> only use the raw transaction methods if
0831:             * you really know what you're doing. It's almost always better to use the
0832:             * {@link DbQueryManager#inTransaction(DbTransactionUser) inTransaction}
0833:             * method of the <code>DbQueryManager</code> class instead.
0834:             * <p>Commits an active transaction.
0835:             * <p>All transaction-related resources are cleared and all the threads
0836:             * that are waiting for the transaction to terminate are woken up.
0837:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0838:             * automatically closed and if it's part of a pool, all the other
0839:             * connections are closed too and the pool is set up again. Also, any
0840:             * ongoing transaction will be rolled-back automatically.
0841:             * 
0842:             * @return <code>true</code> if the transaction was successfully
0843:             * committed; or
0844:             * <p><code>false</code> if the <code>Datasource</code> doesn't support
0845:             * transactions, or when no transaction is active on this
0846:             * <code>DbConnection</code>, or when the executing thread isn't the
0847:             * thread that began the transaction.
0848:             * @exception DatabaseException when an error occurred during the commit
0849:             * of the active transaction, or when the active transaction has
0850:             * timed-out.
0851:             * @see DbQueryManager#inTransaction(DbTransactionUser)
0852:             * @see #supportsTransactions()
0853:             * @see #beginTransaction()
0854:             * @see #rollback()
0855:             * @see #isFree()
0856:             * @see #isTransactionValidForThread()
0857:             * @since 1.0
0858:             */
0859:            public boolean commit() throws DatabaseException {
0860:                // if the datasource doesn't support transactions,
0861:                // it's impossible to commit one
0862:                if (!supportsTransactions()) {
0863:                    return false;
0864:                }
0865:
0866:                synchronized (this ) {
0867:                    // if the transaction isn't valid for the current thread
0868:                    // refuse to commit it
0869:                    if (!isTransactionValidForThread()) {
0870:                        return false;
0871:                    }
0872:                }
0873:
0874:                try {
0875:                    detectCleanup();
0876:
0877:                    mConnection.commit();
0878:                    mConnection.setAutoCommit(true);
0879:                } catch (SQLException e) {
0880:                    handleException();
0881:                    throw new TransactionCommitErrorException(mDatasource, e);
0882:                } finally {
0883:                    synchronized (this ) {
0884:                        if (mTransactionThread != null) {
0885:                            mTransactionThread = null;
0886:                        }
0887:
0888:                        this .notifyAll();
0889:                    }
0890:
0891:                    mDatasource.getPool().unregisterThreadConnection(
0892:                            Thread.currentThread());
0893:                }
0894:
0895:                return true;
0896:            }
0897:
0898:            /**
0899:             * <p><strong>Warning:</strong> only use the raw transaction methods if
0900:             * you really know what you're doing. It's almost always better to use the
0901:             * {@link DbQueryManager#inTransaction(DbTransactionUser) inTransaction}
0902:             * method of the <code>DbQueryManager</code> class instead.
0903:             * <p>Rolls-back an active transaction.
0904:             * <p>All transaction-related resources are cleared and all the threads
0905:             * that are waiting for the transaction to terminate are woken up.
0906:             * <p>If an exception is thrown, this <code>DbConnection</code> is
0907:             * automatically closed and if it's part of a pool, all the other
0908:             * connections are closed too and the pool is set up again. Also, any
0909:             * ongoing transaction will be rolled-back automatically.
0910:             * 
0911:             * @return <code>true</code> if the transaction was successfully
0912:             * rolled-back; or
0913:             * <p><code>false</code> if the <code>Datasource</code> doesn't support
0914:             * transactions, or when no transaction is active on this
0915:             * <code>DbConnection</code>, or when the executing thread isn't the
0916:             * thread that began the transaction.
0917:             * @exception DatabaseException when an error occurred during the rollback
0918:             * of the active transaction, or when the active transaction has
0919:             * timed-out.
0920:             * @see DbQueryManager#inTransaction(DbTransactionUser)
0921:             * @see #supportsTransactions()
0922:             * @see #beginTransaction()
0923:             * @see #commit()
0924:             * @see #isFree()
0925:             * @see #isTransactionValidForThread()
0926:             * @since 1.0
0927:             */
0928:            public boolean rollback() throws DatabaseException {
0929:                // if the datasource doesn't support transactions,
0930:                // it's impossible to roll one back
0931:                if (!supportsTransactions()) {
0932:                    return false;
0933:                }
0934:
0935:                synchronized (this ) {
0936:                    // if the transaction isn't valid for the current thread
0937:                    // refuse to roll it back
0938:                    if (!isTransactionValidForThread()) {
0939:                        return false;
0940:                    }
0941:                }
0942:
0943:                try {
0944:                    detectCleanup();
0945:
0946:                    mConnection.rollback();
0947:                    mConnection.setAutoCommit(true);
0948:                } catch (SQLException e) {
0949:                    handleException();
0950:                    throw new TransactionRollbackErrorException(mDatasource, e);
0951:                } finally {
0952:                    synchronized (this ) {
0953:                        if (mTransactionThread != null) {
0954:                            mTransactionThread = null;
0955:                        }
0956:
0957:                        this .notifyAll();
0958:                    }
0959:
0960:                    mDatasource.getPool().unregisterThreadConnection(
0961:                            Thread.currentThread());
0962:                }
0963:
0964:                return true;
0965:            }
0966:
0967:            /**
0968:             * Indicates whether this <code>DbConnection</code> is free to execute
0969:             * statements for the current thread.
0970:             * 
0971:             * @return <code>true</code> if a statement can be executed by the current
0972:             * thread on this <code>DbConnection</code>; or
0973:             * <p><code>false</code> if the connection is closed or when a transaction
0974:             * is already active on this <code>DbConnection</code> for another thread.
0975:             * @see #supportsTransactions()
0976:             * @see #beginTransaction()
0977:             * @see #commit()
0978:             * @see #rollback()
0979:             * @see #isTransactionValidForThread()
0980:             * @since 1.0
0981:             */
0982:            public boolean isFree() {
0983:                synchronized (this ) {
0984:                    if (isCleanedUp()) {
0985:                        return false;
0986:                    }
0987:
0988:                    if (!hasTransactionThread()) {
0989:                        return true;
0990:                    }
0991:
0992:                    if (isTransactionValidForThread()) {
0993:                        return true;
0994:                    }
0995:
0996:                    return false;
0997:                }
0998:            }
0999:
1000:            /**
1001:             * Indicates whether this connections has an active transaction thread.
1002:             * 
1003:             * @return <code>true</code> is an active transaction thread is present;
1004:             * or
1005:             * <p><code>false</code> otherwise.
1006:             */
1007:            private boolean hasTransactionThread() {
1008:                return mTransactionThread != null;
1009:            }
1010:
1011:            /**
1012:             * Indicates whether the current thread has a valid transaction going on
1013:             * for the execution of statements.
1014:             * <p>If an exception is thrown, this <code>DbConnection</code> is
1015:             * automatically closed and if it's part of a pool, all the other
1016:             * connections are closed too and the pool is set up again.
1017:             * 
1018:             * @return <code>true</code> if a transaction is active that can be used
1019:             * by the current thread; or
1020:             * <p><code>false</code> if the connection is closed, doesn't support
1021:             * transactions, has no active transaction or has a transaction that was
1022:             * started by another thread.
1023:             * @exception DatabaseException when errors occurred during the
1024:             * verification of the connection's open status and support for
1025:             * transactions
1026:             * @see #supportsTransactions()
1027:             * @see #beginTransaction()
1028:             * @see #commit()
1029:             * @see #rollback()
1030:             * @see #isFree()
1031:             * @since 1.0
1032:             */
1033:            public boolean isTransactionValidForThread() {
1034:                synchronized (this ) {
1035:                    if (!hasTransactionThread()) {
1036:                        return false;
1037:                    }
1038:
1039:                    return mTransactionThread == Thread.currentThread();
1040:
1041:                }
1042:            }
1043:
1044:            /**
1045:             * Indicates whether this <code>DbConnection</code>'s connection to the
1046:             * database is closed.
1047:             * <p>If an exception is thrown, this <code>DbConnection</code> is
1048:             * automatically cleaned up. Also, any ongoing transaction will be
1049:             * rolled-back automatically.
1050:             * 
1051:             * @return <code>true</code> when this <code>DbConnection</code> is
1052:             * closed; or
1053:             * <p><code>false</code> if it's connected.
1054:             * @exception DatabaseException when an error occurred during the
1055:             * verification of the JDBC connection's closed status
1056:             * @since 1.0
1057:             */
1058:            public boolean isClosed() throws DatabaseException {
1059:                try {
1060:                    if (null == mConnection) {
1061:                        return true;
1062:                    }
1063:
1064:                    return mConnection.isClosed();
1065:                } catch (SQLException e) {
1066:                    cleanup();
1067:                    throw new ConnectionStatusErrorException(mDatasource, e);
1068:                }
1069:            }
1070:
1071:            /**
1072:             * Retrieves a <code>DatabaseMetaData</code> object that contains metadata
1073:             * about the database to which this <code>DbConnection</code> object
1074:             * represents a connection. The metadata includes information about the
1075:             * database's tables, its supported SQL grammar, its stored procedures,
1076:             * the capabilities of this connection, and so on.
1077:             * <p>If an exception is thrown, this <code>DbConnection</code> is
1078:             * automatically closed and if it's part of a pool, all the other
1079:             * connections are closed too and the pool is set up again. Also, any
1080:             * ongoing transaction will be rolled-back automatically.
1081:             * 
1082:             * @return a <code>DatabaseMetaData</code> object for this
1083:             * <code>DbConnection</code> instance; or
1084:             * <p><code>null</code> if the <code>DbConnection</code> instance is not
1085:             * connected.
1086:             * @exception DatabaseException if a database access error occurs
1087:             */
1088:            public DatabaseMetaData getMetaData() throws DatabaseException {
1089:                try {
1090:                    detectCleanup();
1091:
1092:                    return mConnection.getMetaData();
1093:                } catch (SQLException e) {
1094:                    handleException();
1095:                    throw new ConnectionMetaDataErrorException(mDatasource, e);
1096:                }
1097:            }
1098:
1099:            /**
1100:             * Attempts to change the transaction isolation level for this
1101:             * <code>DbConnection</code> object to the one given. The constants
1102:             * defined in the interface <code>Connection</code> are the possible
1103:             * transaction isolation levels.
1104:             * 
1105:             * @param level transaction isolation level constant defined in the <code>{@link
1106:             * java.sql.Connection Connection}</code> interface
1107:             * @exception DatabaseException if a database access error occurs
1108:             * @see java.sql.Connection
1109:             */
1110:            public void setTransactionIsolation(int level)
1111:                    throws DatabaseException {
1112:                try {
1113:                    detectCleanup();
1114:
1115:                    mConnection.setTransactionIsolation(level);
1116:                } catch (SQLException e) {
1117:                    handleException();
1118:                    throw new ConnectionMetaDataErrorException(mDatasource, e);
1119:                }
1120:            }
1121:
1122:            /**
1123:             * Ensures that this <code>DbConnection</code> is correctly cleaned-up
1124:             * when it's garbage collected.
1125:             * 
1126:             * @exception Throwable if an error occurred during the finalization
1127:             * @since 1.0
1128:             */
1129:            protected void finalize() throws Throwable {
1130:                synchronized (this ) {
1131:                    cleanup();
1132:                    this .notifyAll();
1133:                }
1134:
1135:                super .finalize();
1136:            }
1137:
1138:            /**
1139:             * Simply clones the instance with the default clone method. This creates
1140:             * a shallow copy of all fields and the clone will in fact just be another
1141:             * reference to the same underlying data. The independence of each cloned
1142:             * instance is consciously not respected since they rely on resources that
1143:             * can't be cloned.
1144:             * 
1145:             * @since 1.0
1146:             */
1147:            public Object clone() {
1148:                try {
1149:                    return super .clone();
1150:                } catch (CloneNotSupportedException e) {
1151:                    // this should never happen
1152:                    Logger.getLogger("com.uwyn.rife.database").severe(
1153:                            ExceptionUtils.getExceptionStackTrace(e));
1154:                    return null;
1155:                }
1156:            }
1157:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.