001: /*
002: * $Id: PooledConnection.java,v 1.2 2002/09/16 08:05:03 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.database;
011:
012: import java.io.IOException;
013:
014: /**
015: * Abstract class wrapping connection objects.
016: *
017: * @version $Revision: 1.2 $
018: * @author Jani Lehtimäki
019: */
020: public abstract class PooledConnection {
021:
022: /**
023: * Pool where this connections belongs into.
024: */
025: protected ConnectionPool myPool;
026:
027: /**
028: * Name of connection "[name_of_pool]-[count]".
029: */
030: protected String name;
031:
032: /**
033: * Connection object
034: */
035: protected Object connection;
036:
037: /**
038: * Timeout
039: */
040: protected int timeout = 0;
041:
042: /**
043: * Creation timestamp.
044: */
045: protected long createdAt;
046:
047: /**
048: * Closing timestamp.
049: */
050: protected long closedAt = 0;
051:
052: /**
053: * Timestamp for last reserve.
054: */
055: protected long reservedAt = 0;
056:
057: /**
058: * Timestamp for last release.
059: */
060: protected long releasedAt = 0;
061:
062: /**
063: * Being reserved?
064: */
065: protected boolean reserved = false;
066:
067: /**
068: * Creates the connection.
069: *
070: * @param myPool Connection pool
071: * @param name Name of connection
072: * @param connection java.sql.Connection
073: */
074: public PooledConnection(ConnectionPool myPool, String name,
075: Object connection) {
076: this .myPool = myPool;
077: this .name = name;
078: this .connection = connection;
079: this .createdAt = System.currentTimeMillis();
080: this .timeout = myPool.getConnectionTimeout();
081: }
082:
083: /**
084: * Gets the name of connection.
085: *
086: * @return Name of connection
087: */
088: public String getName() {
089: return name;
090: }
091:
092: /**
093: * Gets the pool where connection belongs into.
094: *
095: * @return Connection pool
096: */
097: public ConnectionPool getPool() {
098: return myPool;
099: }
100:
101: /**
102: * Is this connection reserved?
103: *
104: * @return <code>true</code> if reserved, <code>false</code> otherwise.
105: */
106: public boolean isReserved() {
107: return reserved;
108: }
109:
110: /**
111: * Timestamp of creation time.
112: *
113: * @return Timestamp
114: */
115: public long getCreationTime() {
116: return createdAt;
117: }
118:
119: /**
120: * Timestamp of last close.
121: *
122: * @return Timestamp
123: */
124: public long getClosingTime() {
125: return closedAt;
126: }
127:
128: /**
129: * Timestamp of last reservation.
130: *
131: * @return Timestamp
132: */
133: public long getReserveTime() {
134: return reservedAt;
135: }
136:
137: /**
138: * Timestamp of last release.
139: *
140: * @return Timestamp
141: */
142: public long getReleaseTime() {
143: return releasedAt;
144: }
145:
146: /**
147: * Gets the connection object.
148: *
149: * @return Connection
150: */
151: public Object getConnection() {
152: return connection;
153: }
154:
155: protected abstract boolean isConnectionClosed() throws Exception;
156:
157: protected abstract void closeConnection() throws Exception;
158:
159: /**
160: * Checks if the connection is still alive. Connection is
161: * considered alive if <code>java.sql.Connection</code> has not yet
162: * been closed, and maximum lifetime is not exceeded. However,
163: * lifetime can be exceeded if connection is reserved.
164: *
165: * @return <code>true</code> if alive, <code>false</code> otherwise.
166: */
167: public boolean isAlive() {
168: try {
169: if (connection == null || isConnectionClosed()) {
170: return false;
171: }
172: } catch (Exception exception) {
173: myPool.connectionException("PooledConnection.isAlive()",
174: exception);
175: return false;
176: }
177:
178: if (!reserved) {
179:
180: /*
181: * Ensures that reserved connections can live longer than
182: * their preferred lifetime
183: */
184: if ((System.currentTimeMillis() - createdAt) > myPool
185: .getConnectionLifetime()) {
186: return false;
187: }
188: }
189:
190: return true;
191: }
192:
193: /**
194: * Checks if the connection has timed out. It is considered
195: * timed out if it is reserved and maximum reservation time
196: * has been exceeded.
197: *
198: * @return <code>true</code> if timed out, <code>false</code> otherwise.
199: */
200: public boolean hasTimedOut() {
201: if (reserved) {
202: if ((System.currentTimeMillis() - reservedAt) > timeout) {
203: return true;
204: }
205: }
206:
207: return false;
208: }
209:
210: /**
211: * Marks the connection reserved.
212: */
213: /*package*/void reserve(int timeout) {
214: if (!reserved) {
215: reserved = true;
216: reservedAt = System.currentTimeMillis();
217: this .timeout = (timeout > 0) ? timeout : myPool
218: .getConnectionTimeout();
219: }
220: }
221:
222: /**
223: * Releases the connection
224: */
225: public void release() {
226: if (reserved) {
227: reserved = false;
228: releasedAt = System.currentTimeMillis();
229: myPool.release(this );
230: }
231: }
232:
233: private void doClose() {
234: if (reserved) {
235: reserved = false;
236: releasedAt = System.currentTimeMillis();
237: }
238:
239: if (connection != null) {
240: try {
241: if (!isConnectionClosed()) {
242: closeConnection();
243: }
244: } catch (Exception exception) {
245: myPool.connectionException(
246: "PooledConnection.isAlive()", exception);
247: }
248:
249: connection = null;
250: }
251:
252: closedAt = System.currentTimeMillis();
253: }
254:
255: /*package*/void close() {
256: doClose();
257: myPool.connectionClosed(this );
258: }
259:
260: /*package*/void timeout() {
261: doClose();
262: myPool.connectionTimeout(this );
263: }
264:
265: public boolean equals(Object o) {
266: return this == o;
267: }
268:
269: public String toString() {
270: return getName();
271: }
272:
273: }
|