001: /*
002: * XAPool: Open Source XA JDBC Pool
003: * Copyright (C) 2003 Objectweb.org
004: * Initial Developer: Lutris Technologies Inc.
005: * Contact: xapool-public@lists.debian-sf.objectweb.org
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020: * USA
021: */
022: package org.enhydra.jdbc.standard;
023:
024: import org.enhydra.jdbc.util.Logger;
025:
026: import java.sql.Connection;
027: import java.sql.SQLException;
028: import java.util.Vector;
029: import javax.sql.ConnectionEvent;
030: import javax.sql.ConnectionEventListener;
031: import javax.sql.PooledConnection;
032:
033: /**
034: * Provides an implementation of javax.sql.PooledConnection which
035: * is completely generic (i.e. it relies only on JDBC 1 functionality).
036: *
037: * This class maintains a physical database connection which is
038: * passed to each StandardXAConnectionHandle when it is created. It is the
039: * StandardXAConnectionHandle object which the application receives and which
040: * it perceives as the java.sql.Connection object.
041: *
042: * StandardXAConnectionHandle objects pass PreparedStatements back to the
043: * StandardPooledConnection so that they can be retained across
044: * StandardXAConnectionHandle instantiations.
045: */
046: public class StandardPooledConnection implements PooledConnection {
047:
048: protected StandardConnectionPoolDataSource dataSource;
049: public Connection con; // the physical database connection
050: public StandardConnectionHandle connectionHandle;
051: // the last StandardConnectionHandle created
052: Vector listeners; // objects listening for events on this connection
053: boolean isClosed; // true if this connection has been closed
054: public Logger log;
055:
056: /**
057: * Creates the physical database connection.
058: */
059: public StandardPooledConnection(
060: StandardConnectionPoolDataSource dataSource, String user,
061: String password) throws SQLException {
062: this .dataSource = dataSource;
063: con = dataSource.getConnection(user, password);
064: listeners = new Vector(5, 5);
065: }
066:
067: /**
068: * Creates a new StandardConnectionHandle for use by an application.
069: * If there is already a StandardConnectionHandle in use then it is
070: * closed (i.e. the application has the connection withdrawn).
071: */
072: synchronized public Connection getConnection()
073: throws java.sql.SQLException {
074: if (connectionHandle != null) {
075: // if there's already a connection handle
076: if (!connectionHandle.isClosed()) { // and it hasn't been closed
077: connectionHandle.close(); // close it now
078: }
079: }
080: newConnectionHandle();
081: return connectionHandle;
082: }
083:
084: protected void newConnectionHandle() {
085: log.debug("StandardPooledConnection:newConnectionHandle");
086: connectionHandle = new StandardConnectionHandle(this ,
087: dataSource.getMasterPrepStmtCache(), dataSource
088: .getPreparedStmtCacheSize());
089: }
090:
091: public void close() throws java.sql.SQLException {
092: con.close();
093: dataSource.getMasterPrepStmtCache().remove(con.toString());
094: }
095:
096: public void addConnectionEventListener(
097: ConnectionEventListener listener) {
098: listeners.addElement(listener);
099: }
100:
101: public void removeConnectionEventListener(
102: ConnectionEventListener listener) {
103: listeners.removeElement(listener);
104: }
105:
106: /**
107: * Notifies all listeners that the StandardConnectionHandle created by this
108: * PooledConnection has been closed.
109: */
110: void closeEvent() {
111: ConnectionEvent event = new ConnectionEvent(this );
112: // create the event that we'll send
113: for (int i = 0; i < listeners.size(); i++) { // for each listener
114: Object obj = listeners.elementAt(i); // get next listener
115: ConnectionEventListener cel = (ConnectionEventListener) obj;
116: //cast to something more useful
117: cel.connectionClosed(event); // notify this listener
118: }
119:
120: }
121:
122: /**
123: * Invoked when a fatal connection error occurs,
124: * just before an SQLException is thrown to the application
125: *
126: * This method is automatically called when a fatal error
127: * is detected on the base connection. The base connection
128: * is the actual connection that backs the connection
129: * handle provided by the getConnection() method
130: */
131: public void connectionErrorOccurred(ConnectionEvent event) {
132: for (int i = 0; i < listeners.size(); i++) { // for each listener
133: Object obj = listeners.elementAt(i); // get next listener
134: ConnectionEventListener cel = (ConnectionEventListener) obj;
135: //cast to something more useful
136: cel.connectionErrorOccurred(event); // notify this listener
137: //cel.connectionClosed (event); // notify this listener
138: }
139: }
140:
141: /**
142: * Access method allowing access to the underlying physical connection.
143: */
144: public Connection getPhysicalConnection() {
145: return con;
146: }
147:
148: public void setLogger(Logger alog) {
149: log = alog;
150: }
151:
152: public String toString() {
153: try {
154: StringBuffer sb = new StringBuffer();
155: sb.append("StandardPooledConnection:\n");
156: sb.append(" is closed local=<" + this .isClosed + ">\n");
157: sb.append(" is closed con=<" + con.isClosed() + ">\n");
158: sb.append(" connection =<" + this .con + ">\n");
159:
160: return sb.toString();
161: } catch (Exception e) {
162: e.printStackTrace();
163: return null;
164: }
165: }
166: }
|